This commit is contained in:
Michael Pfaff 2022-05-30 07:40:22 -04:00
parent df882cb64c
commit 5ce0f242f6
Signed by: michael
GPG Key ID: CF402C4A012AA9D4
2 changed files with 33 additions and 103 deletions

View File

@ -94,11 +94,12 @@ pub trait DynamicQuery {
/// A type defining the fields to include in the filtered structure. /// A type defining the fields to include in the filtered structure.
type Definition; type Definition;
/// Filters the fields of this structure in place. /// Filters the fields of this structure in place according to the `def`.
fn filter_ref(&mut self, def: &Self::Definition); fn filter_ref(&mut self, def: &Self::Definition);
/// Filters the fields of this structure in place. This method takes ownership of the /// Filters the fields of this structure in place according to the `def`.
/// structure, making it more suitable for pipelines. /// This method takes ownership of the structure, making it more suitable
/// for pipelines.
#[inline(always)] #[inline(always)]
fn filter(mut self, def: &Self::Definition) -> Self fn filter(mut self, def: &Self::Definition) -> Self
where where
@ -177,18 +178,24 @@ mod tests {
bars: Some(vec![]), bars: Some(vec![]),
bars_by_bazs: Some(std::collections::HashMap::new()), bars_by_bazs: Some(std::collections::HashMap::new()),
}; };
assert_eq!(serde_json::to_string(&x).ok(), Some(r#"{"baz_inner":true,"baz":false,"bars":[],"bars_by_bazs":{}}"#.to_owned())); assert_eq!(
serde_json::to_string(&x).ok(),
Some(r#"{"baz_inner":true,"baz":false,"bars":[],"bars_by_bazs":{}}"#.to_owned())
);
assert_eq!(x.clone().filter(&FooDef { assert_eq!(
x.clone().filter(&FooDef {
bar: false, bar: false,
baz: true, baz: true,
bars: Some(BarDef::default()), bars: Some(BarDef::default()),
bars_by_bazs: None, bars_by_bazs: None,
}), Foo { }),
Foo {
bar: None, bar: None,
baz: Some(false), baz: Some(false),
bars: Some(vec![]), bars: Some(vec![]),
bars_by_bazs: None, bars_by_bazs: None,
}) }
)
} }
} }

View File

@ -95,8 +95,6 @@ macro_rules! query_def_internal_struct {
$( #[$field_meta:meta] )* $( #[$field_meta:meta] )*
$field:ident: $( $qualifier:lifetime )? ($( $type:tt )+) $field:ident: $( $qualifier:lifetime )? ($( $type:tt )+)
),+ ),+
$(,)?
} }
) => { ) => {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -179,11 +177,8 @@ macro_rules! query_def_internal_enum {
$( #[$variant_def_field_meta:meta] )+ $( #[$variant_def_field_meta:meta] )+
))?: $( $qualifier:lifetime )? ($( $type:tt )+) ))?: $( $qualifier:lifetime )? ($( $type:tt )+)
),+ ),+
$(,)?
})? })?
),+ ),+
$(,)?
} }
) => { ) => {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -272,8 +267,8 @@ macro_rules! query_def_0 {
))? { ))? {
$( $(
$( #[$field_meta] )* $( #[$field_meta] )*
$field: $( $qualifier )? ($( $type )+), $field: $( $qualifier )? ($( $type )+)
)+ ),+
} }
} }
}; };
@ -394,8 +389,8 @@ macro_rules! query_def_0 {
$( #[$field_meta] )* $( #[$field_meta] )*
$field( $field(
#[serde(default)] #[serde(default)]
): $( $qualifier )? ($( $type )+), ): $( $qualifier )? ($( $type )+)
)+ ),+
})? })?
),+ ),+
} }
@ -405,79 +400,7 @@ macro_rules! query_def_0 {
/// Defines a dynamic query structure. /// Defines a dynamic query structure.
/// ///
/// # Structs /// See the crate documentation for details.
///
/// Only struct structs (yes, that is what they're [called](https://doc.rust-lang.org/reference/items/structs.html)), are supported. Struct structs with no fields are also not supported.
///
/// This fails:
/// ```compile_fail
/// # #[macro_use] extern crate ql;
/// #
/// query_def! {
/// struct Foo {
/// }
/// }
/// #
/// # fn main() {
/// # }
/// ```
///
/// This works:
/// ```
/// # #[macro_use] extern crate ql;
/// #
/// query_def! {
/// struct Foo {
/// a: (bool),
/// b: (usize),
/// c: (String),
/// d: (Vec<String>),
/// }
/// }
/// #
/// # fn main() {
/// # }
/// ```
///
/// # Enums
///
/// Fieldless and struct enums are supported, but struct enums with no fields are not.
///
/// This fails:
/// ```compile_fail
/// # #[macro_use] extern crate ql;
/// #
/// query_def! {
/// enum Foo {
/// A { }
/// }
/// }
/// #
/// # fn main() {
/// # }
/// ```
///
/// This works:
/// ```
/// # #[macro_use] extern crate ql;
/// #
/// query_def! {
/// enum Foo {
/// A
/// }
/// }
/// #
/// # fn main() {
/// # }
/// ```
///
/// Incorrect syntax in the macro invocation can lead to very confusing errors.
///
/// For example, the incorrect enum syntax shown earlier will fail with this message:
///
/// ```text
/// error: no rules expected the token `struct`
/// ```
#[macro_export] #[macro_export]
macro_rules! query_def { macro_rules! query_def {
($( ($(