105 lines
2.1 KiB
Rust
105 lines
2.1 KiB
Rust
/// A dynamic query structure.
|
|
pub trait DynamicQuery {
|
|
type Definition;
|
|
|
|
fn filter_ref(&mut self, def: &Self::Definition);
|
|
|
|
#[inline(always)]
|
|
fn filter(mut self, def: &Self::Definition) -> Self
|
|
where
|
|
Self: Sized,
|
|
{
|
|
self.filter_ref(def);
|
|
self
|
|
}
|
|
}
|
|
|
|
// needed for macros
|
|
#[doc(hidden)]
|
|
pub use paste;
|
|
|
|
mod macros;
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
use super::DynamicQuery;
|
|
|
|
// just tests that the macro compiles
|
|
crate::query_def_struct! {
|
|
/// Foo doc.
|
|
#[derive(PartialEq)]
|
|
Foo {
|
|
/// Field doc.
|
|
#[serde(flatten)]
|
|
bar: (Bar),
|
|
baz: (bool),
|
|
bars: 'vec (Bar),
|
|
bars_by_bazs: 'map (bool, Bar),
|
|
}
|
|
|
|
/// Bar doc.
|
|
#[derive(PartialEq)]
|
|
Bar {
|
|
baz_inner: (bool),
|
|
}
|
|
}
|
|
|
|
crate::query_def_enum! {
|
|
FooOrBar {
|
|
Foo {
|
|
value: 'dyn (Foo),
|
|
},
|
|
|
|
Bar {
|
|
value: 'dyn (Bar),
|
|
}
|
|
}
|
|
|
|
OptionalFooOrBarDyn {
|
|
Some {
|
|
value: 'dyn (FooOrBar),
|
|
},
|
|
|
|
None {
|
|
}
|
|
}
|
|
|
|
OptionalFooOrBar {
|
|
Some {
|
|
value: (FooOrBar),
|
|
},
|
|
|
|
None {
|
|
}
|
|
}
|
|
}
|
|
|
|
// make sure A. serde is working and B. we get expected structure
|
|
#[test]
|
|
fn test_json() {
|
|
let x = Foo {
|
|
bar: Some(Bar {
|
|
baz_inner: Some(true),
|
|
}),
|
|
baz: Some(false),
|
|
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!(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,
|
|
})
|
|
}
|
|
}
|