Macro mongodm::field[][src]

macro_rules! field {
    ( $($tt:tt)* ) => { ... };
}
Expand description

Statically check presence of field in a given struct and stringify it.

Note that it sadly won’t work with #[serde(rename = "...")] and #[serde(rename_all = "...")].

Example

use mongodm::mongo::bson::doc;
use mongodm::field;
use mongodm::operator::*;

struct MyModel {
    foo: i64,
    bar: i64,
    lorem: String,
}

// Statically checked
let a = doc! {
    And: [
        { field!(foo in MyModel): { Exists: true } },
        {
            Or: [
                { field!(bar in MyModel): { GreaterThan: 100 } },
                { field!(lorem in MyModel): "ipsum" }
            ]
        },
        // dollar and double dollar signs can inserted by prefixing with @
        { field!(@foo in MyModel): field!(@@bar in MyModel) }
    ]
};

// Hardcoded strings
let b = doc! {
    "$and": [
        { "foo": { "$exists": true } },
        {
            "$or": [
                { "bar": { "$gt": 100 } },
                { "lorem": "ipsum" }
            ]
        },
        { "$foo": "$$bar" }
    ]
};

// Generated document are identicals
assert_eq!(a, b);

Nested structs

use mongodm::mongo::bson::doc;
use mongodm::field;

struct Foo {
    bar: Bar,
}

struct Bar {
    lorem: String,
    baz: Baz,
}

struct Baz {
    dolor: String,
}

assert_eq!(
    doc! { field!((bar in Foo).(lorem in Bar)): "ipsum" },
    doc! { "bar.lorem": "ipsum" },
);

assert_eq!(
    doc! { field!((bar in Foo).(baz in Bar).(dolor in Baz)): "sit amet" },
    doc! { "bar.baz.dolor": "sit amet" },
);

assert_eq!(
    doc! { field!(@@(bar in Foo).(baz in Bar).(dolor in Baz)): "sit amet" },
    doc! { "$$bar.baz.dolor": "sit amet" },
);

If the field doesn’t exist, compilation will fail.

struct MyModel {
    foo: i64,
    bar: Bar,
}

struct Bar {
    baz: i64,
}

// Doesn't compile because `baz` isn't a member of `MyModel`
doc! { field!(baz in MyModel): 0 };
// Doesn't compile because `foo` isn't a member of `Bar`
doc! { field!((bar in MyModel).(foo in Bar)): 0 };
// Doesn't compile because `foo` isn't a `Bar`
doc! { field!((foo in MyModel).(baz in Bar)): 0 };
// Fail because `b` is not a field of `Third`
doc! { field!((bar in MyModel).(third in Bar).(b in Third)): 0 };