const APPEND_TO_QUERY_OPTIONS: [(&str, crate::attributes::OptionKind); 1] =
[("columns", crate::attributes::OptionKind::Path)];
#[derive(Debug, PartialEq, Eq)]
pub struct TopLevelMeta {
pub columns: syn::Path,
pub runtime_crate: Option<syn::Path>,
}
impl crate::steps::TopLevelMeta for TopLevelMeta {
fn from_attributes(attributes: &[syn::Attribute]) -> syn::Result<Self> {
let columns = crate::attributes::required_path_option(
attributes,
"append_conditions",
"columns",
&APPEND_TO_QUERY_OPTIONS,
"Name the entity (deriving Columns) that stores the wrapped filters' fields: #[append_conditions(columns = path)]",
);
let runtime_crate = crate::attributes::crate_option(attributes);
let (columns, runtime_crate) = crate::errors::both(columns, runtime_crate)?;
Ok(Self {
columns,
runtime_crate,
})
}
}
#[cfg(test)]
mod tests {
fn parse(item: proc_macro2::TokenStream) -> syn::Result<super::TopLevelMeta> {
let attributes = syn::parse2::<syn::DeriveInput>(item).unwrap().attrs;
crate::steps::TopLevelMeta::from_attributes(&attributes)
}
#[test]
fn test_parsing_top_level_meta_succeeds_when_all_preconditions_are_met() {
let top_level_meta = parse(quote::quote! {
#[derive(Debug, AppendConditions)]
#[append_conditions(columns = crate::entities::order::Order)]
pub struct OrdersFilterOptionsModelWrapper(pub OrdersFilterOptionsModel);
})
.unwrap();
pretty_assertions::assert_eq!(
top_level_meta,
super::TopLevelMeta {
columns: syn::parse_str("crate::entities::order::Order").unwrap(),
runtime_crate: None,
}
);
}
#[test]
fn test_parsing_top_level_meta_rejects_a_filters_option() {
assert!(
parse(quote::quote! {
#[append_conditions(columns = crate::entities::order::Order, filters = Other)]
pub struct OrdersFilterOptionsModelWrapper(pub OrdersFilterOptionsModel);
})
.is_err()
);
}
#[test]
fn test_parsing_top_level_meta_fails_without_columns() {
assert!(
parse(quote::quote! {
pub struct OrdersFilterOptionsModelWrapper(pub OrdersFilterOptionsModel);
})
.is_err()
);
}
}