diesel

Macro infix_operator

Source
macro_rules! infix_operator {
    ($name:ident, $operator:expr) => { ... };
    ($name:ident, $operator:expr, backend: $backend:ty) => { ... };
    ($name:ident, $operator:expr, $($return_ty:tt)::*) => { ... };
    ($name:ident, $operator:expr, $($return_ty:tt)::*, backend: $backend:ty) => { ... };
}
Expand description

Useful for libraries adding support for new SQL types. Apps should never need to call this.

This will create a new type with the given name. It will implement all methods needed to be used as an expression in Diesel, placing the given SQL between the two elements. The third argument specifies the SQL type that the operator returns. If it is not given, the type will be assumed to be Bool.

If the operator is specific to a single backend, you can specify this by adding backend: Pg or similar as the last argument.

It should be noted that the generated impls will not constrain the SQL types of the arguments. You should ensure that they are of the right type in your function which constructs the operator.

Typically you would not expose the type that this generates directly. You’d expose a function (or trait) used to construct the expression, and a helper type which represents the return type of that function. See the source of diesel::expression::expression_methods and diesel::expression::helper_types for real world examples of this.

§Examples

§Possible invocations

// The SQL type will be boolean. The backend will not be constrained
infix_operator!(Matches, " @@ ");

// Queries which try to execute `Contains` on a backend other than Pg
// will fail to compile
infix_operator!(Contains, " @> ", backend: Pg);

// The type of `Concat` will be `TsVector` rather than Bool
infix_operator!(Concat, " || ", TsVector);

// It is perfectly fine to have multiple operators with the same SQL.
// Diesel will ensure that the queries are always unambiguous in which
// operator applies
infix_operator!(Or, " || ", TsQuery);

// Specifying both the return types and the backend
infix_operator!(And, " && ", TsQuery, backend: Pg);

§Example usage

diesel::infix_operator!(MyEq, " = ");

use diesel::expression::AsExpression;

// Normally you would put this on a trait instead
fn my_eq<T, U, ST>(left: T, right: U) -> MyEq<T, U::Expression> where
    T: Expression<SqlType = ST>,
    U: AsExpression<ST>,
    ST: SqlType + TypedExpressionType,
{
    MyEq::new(left, right.as_expression())
}

let users_with_name = users.select(id).filter(my_eq(name, "Sean"));

assert_eq!(Ok(1), users_with_name.first(connection));