ql.rs/src/lib.rs

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,
})
}
}