Skip to content

Commit 50f6ea3

Browse files
committed
fields! accepts nested structs
1 parent b3e1f9d commit 50f6ea3

File tree

1 file changed

+67
-5
lines changed

1 file changed

+67
-5
lines changed

src/macros.rs

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,55 @@
4848
/// assert_eq!(a, b);
4949
/// ```
5050
///
51+
/// Nested structs
52+
/// ```
53+
/// use mongodm::mongo::bson::doc;
54+
/// use mongodm::field;
55+
///
56+
/// struct Foo {
57+
/// bar: Bar,
58+
/// }
59+
///
60+
/// struct Bar {
61+
/// lorem: String,
62+
/// baz: Baz,
63+
/// }
64+
///
65+
/// struct Baz {
66+
/// dolor: String,
67+
/// }
68+
///
69+
/// assert_eq!(
70+
/// doc! { field!((bar in Foo).(lorem in Bar)): "ipsum" },
71+
/// doc! { "bar.lorem": "ipsum" },
72+
/// );
73+
///
74+
/// assert_eq!(
75+
/// doc! { field!(@@(bar in Foo).(baz in Bar).(dolor in Baz)): "sit amet" },
76+
/// doc! { "$$bar.baz.dolor": "sit amet" },
77+
/// );
78+
/// ```
79+
///
5180
/// If the field doesn't exist, compilation will fail.
5281
///
5382
/// ```compile_fail
5483
/// use mongodm::mongo::bson::doc;
5584
/// use mongodm::field;
56-
/// use mongodm::operator::*;
5785
///
5886
/// struct MyModel {
59-
/// bar: i64,
87+
/// foo: i64,
88+
/// bar: Bar,
89+
/// }
90+
///
91+
/// struct Bar {
92+
/// baz: i64,
6093
/// }
6194
///
62-
/// // Doesn't compile because `foo` isn't a member of `MyModel`
63-
/// doc! { field!(foo in MyModel): 0 };
95+
/// // Doesn't compile because `baz` isn't a member of `MyModel`
96+
/// doc! { field!(baz in MyModel): 0 };
97+
///
98+
/// // Doesn't compile because `foo` isn't a member of `Bar`
99+
/// doc! { field!((bar in MyModel).(foo in Bar)): 0 };
64100
/// ```
65101
#[macro_export]
66102
macro_rules! field {
@@ -69,7 +105,7 @@ macro_rules! field {
69105
const _: fn() = || {
70106
let $type { $field: _, .. };
71107
};
72-
stringify!($field)
108+
stringify!( $field )
73109
}};
74110
( @ $field:ident in $type:path ) => {{
75111
#[allow(unknown_lints, unneeded_field_pattern)]
@@ -85,6 +121,19 @@ macro_rules! field {
85121
};
86122
concat!("$$", stringify!($field))
87123
}};
124+
( ( $field:ident in $type:path ) ) => {{
125+
$crate::field!( $field in $type )
126+
}};
127+
// FIXME: ideally we want a compile-time string instead of format!
128+
( ( $field:ident in $type:path ) . $( $rest:tt ).+ ) => {{
129+
format!("{}.{}", $crate::field!( $field in $type ), $crate::field!( $( $rest ).+ ))
130+
}};
131+
( @ ( $field:ident in $type:path ) . $( $rest:tt ).+ ) => {{
132+
format!("${}.{}", $crate::field!( $field in $type ), $crate::field!( $( $rest ).+ ))
133+
}};
134+
( @ @ ( $field:ident in $type:path ) . $( $rest:tt ).+ ) => {{
135+
format!("$${}.{}", $crate::field!( $field in $type ), $crate::field!( $( $rest ).+ ))
136+
}};
88137
}
89138

90139
/// Shorthand for `field!`.
@@ -145,4 +194,17 @@ macro_rules! f {
145194
( @ @ $field:ident in $type:path ) => {{
146195
$crate::field!( @ @ $field in $type)
147196
}};
197+
( ( $field:ident in $type:path ) ) => {{
198+
$crate::field!( ( $field in $type ) )
199+
}};
200+
( ( $field:ident in $type:path ) . $( $rest:tt ).+ ) => {{
201+
$crate::field!( ( $field in $type ) . $( $rest ).+ )
202+
}};
203+
( @ ( $field:ident in $type:path ) . $( $rest:tt ).+ ) => {{
204+
$crate::field!( @ ( $field in $type ) . $( $rest ).+ )
205+
}};
206+
( @ @ ( $field:ident in $type:path ) . $( $rest:tt ).+ ) => {{
207+
$crate::field!( @ @ ( $field in $type ) . $( $rest ).+ )
208+
}};
148209
}
210+

0 commit comments

Comments
 (0)