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

@ -1,8 +1,8 @@
//! A crate providing a (mostly) straighforward syntax for defining dynamic structures for
//! efficient querying.
//!
//!
//! # Features
//!
//!
//! - Filter a struct or enum according to a query definition.
//! - Inspect definitions manually to avoid unnecessary computations before filtering.
//!
@ -13,7 +13,7 @@
//! this may be supported for all aspects in the future.
//!
//! # Structs
//!
//!
//! 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.
//!
@ -48,9 +48,9 @@
//! ```
//!
//! # Enums
//!
//!
//! Fieldless and struct enums are supported, but struct enums with no fields are not.
//!
//!
//! This fails:
//! ```compile_fail
//! # #[macro_use] extern crate ql;
@ -94,11 +94,12 @@ pub trait DynamicQuery {
/// A type defining the fields to include in the filtered structure.
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);
/// Filters the fields of this structure in place. This method takes ownership of the
/// structure, making it more suitable for pipelines.
/// Filters the fields of this structure in place according to the `def`.
/// This method takes ownership of the structure, making it more suitable
/// for pipelines.
#[inline(always)]
fn filter(mut self, def: &Self::Definition) -> Self
where
@ -177,18 +178,24 @@ mod tests {
bars: Some(vec![]),
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 {
bar: false,
baz: true,
bars: Some(BarDef::default()),
bars_by_bazs: None,
}), Foo {
bar: None,
baz: Some(false),
bars: Some(vec![]),
bars_by_bazs: None,
})
assert_eq!(
x.clone().filter(&FooDef {
bar: false,
baz: true,
bars: Some(BarDef::default()),
bars_by_bazs: None,
}),
Foo {
bar: None,
baz: Some(false),
bars: Some(vec![]),
bars_by_bazs: None,
}
)
}
}

View File

@ -95,8 +95,6 @@ macro_rules! query_def_internal_struct {
$( #[$field_meta:meta] )*
$field:ident: $( $qualifier:lifetime )? ($( $type:tt )+)
),+
$(,)?
}
) => {
#[derive(Debug, Clone)]
@ -146,7 +144,7 @@ macro_rules! query_def_internal_enum_variant_def {
$vis:vis $name:ident {
$( $field:ident$((
$( #[$variant_def_field_meta:meta] )+
))?: $($qualifier:lifetime)? ($($type:tt)+) ),+
))?: $( $qualifier:lifetime )? ($( $type:tt )+) ),+
}
) => {
#[derive(Debug, Clone, Copy, Default)]
@ -179,11 +177,8 @@ macro_rules! query_def_internal_enum {
$( #[$variant_def_field_meta:meta] )+
))?: $( $qualifier:lifetime )? ($( $type:tt )+)
),+
$(,)?
})?
),+
$(,)?
}
) => {
#[derive(Debug, Clone)]
@ -272,8 +267,8 @@ macro_rules! query_def_0 {
))? {
$(
$( #[$field_meta] )*
$field: $( $qualifier )? ($( $type )+),
)+
$field: $( $qualifier )? ($( $type )+)
),+
}
}
};
@ -394,8 +389,8 @@ macro_rules! query_def_0 {
$( #[$field_meta] )*
$field(
#[serde(default)]
): $( $qualifier )? ($( $type )+),
)+
): $( $qualifier )? ($( $type )+)
),+
})?
),+
}
@ -405,79 +400,7 @@ macro_rules! query_def_0 {
/// Defines a dynamic query structure.
///
/// # Structs
///
/// 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`
/// ```
/// See the crate documentation for details.
#[macro_export]
macro_rules! query_def {
($(