From fde0f6224382e83511e4aba30a6fa1d06faf89a7 Mon Sep 17 00:00:00 2001 From: Jacob Phillips Date: Sun, 24 Mar 2024 14:13:19 +0000 Subject: [PATCH] can parse labels --- example/src/person.rs | 2 +- lib/src/entity.rs | 5 +++-- macros/src/derive.rs | 40 ++++++++++++++++++++++++---------------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/example/src/person.rs b/example/src/person.rs index 425d6d0..aa0cbf0 100644 --- a/example/src/person.rs +++ b/example/src/person.rs @@ -27,7 +27,7 @@ mod tests { #[test] fn person() { assert_eq!(Person::typename(), "Person2"); - assert_eq!(Person::labels(), &["Person2, PersonExtraLabel"]); + assert_eq!(Person::labels(), &["Person2", "PersonExtraLabel"]); assert_eq!( Person::field_names(), [ diff --git a/lib/src/entity.rs b/lib/src/entity.rs index 10af706..8a7e57d 100644 --- a/lib/src/entity.rs +++ b/lib/src/entity.rs @@ -55,10 +55,11 @@ pub trait FieldSet: TryFrom { /// Formatted like `typename() { as_query_fields() }`, or for a fieldless relationship, just `typename()`. fn to_query_obj(prefix: Option<&str>, mode: StampMode) -> String { let fields = Self::to_query_fields(prefix, mode); + let labels = Self::labels().join(":"); if fields.is_empty() { - return Self::labels().join(":").to_owned(); + return labels; } - format!("{} {{ {} }}", Self::typename(), fields) + format!("{} {{ {} }}", labels, fields) } } diff --git a/macros/src/derive.rs b/macros/src/derive.rs index ab92cf9..df4234e 100644 --- a/macros/src/derive.rs +++ b/macros/src/derive.rs @@ -6,7 +6,10 @@ pub use node::Node; pub use relation::Relation; use quote::{__private::TokenStream, quote, ToTokens}; -use syn::{Attribute, LitStr, Meta}; +use syn::{ + parse::{Parse, ParseStream}, + Attribute, LitStr, Meta, Result, Token, +}; #[cfg(feature = "serde")] pub fn derive_serde() -> TokenStream { @@ -67,22 +70,10 @@ pub fn parse_labels_meta(meta: &Meta) -> Option> { // Parse #[labels("Foo", "Bar")]. Meta::List(list) => { if list.path.is_ident("labels") { - let mut labels = Vec::new(); - if let Err(e) = list.parse_nested_meta(|meta| { - let label = syn::parse2::(meta.path.into_token_stream()) - .map(|lit| lit.value()) - .unwrap(); - - labels.push(label); - // match meta.path.get_ident() { - // Some(ident) => labels.push(ident.to_string()), - // None => panic!("Expected a label."), - // }; - Ok(()) - }) { - panic!("Expected a list of labels: {}", e); + match list.parse_args::() { + Ok(labels) => Some(labels.0), + Err(e) => panic!("Expected a list of labels: {}", e), } - Some(labels) } else { None } @@ -91,6 +82,23 @@ pub fn parse_labels_meta(meta: &Meta) -> Option> { } } +struct Labels(Vec); + +impl Parse for Labels { + fn parse(input: ParseStream) -> syn::Result { + let mut values = Vec::new(); + while !input.is_empty() { + let lit_str = input.parse::()?; + values.push(lit_str.value()); + if input.is_empty() { + break; + } + input.parse::()?; + } + Ok(Labels(values)) + } +} + #[cfg(test)] mod tests { use syn::parse_quote;