Typed field constants
User::objects(&db) .filter(User::name.icontains("john").or(User::email.ends_with("@example.com"))) .order_by([User::name.asc()])#[derive(Model)] generates one associated constant per field:
pub const name: Field<User, String>. The type parameters encode two
things:
- The model, so a
Field<Post, _>cannot be used by mistake in aUserquery. - The Rust type. Lookups are inherent methods that exist only where
they make sense.
icontainsexists only onField<M, String>, and comparison operands must implementOperand<M, T>. That meansUser::age.eq("x")fails to compile.
A filter!(User, name__icontains = "john") macro was considered and
rejected. The typed-constant API gives IDE completion, rustdoc, and
ordinary compiler errors. A macro would still have to generate these same
constants in order to validate field names.
Django __ traversal is Post::author.join(Author::name) (and further
hops on the joined handle). There are no keyword arguments in Rust, so
name__icontains= is not possible.
Implemented in siderite_orm::expr::{Expr, Field, Operand, Lookup}.