diff --git a/src/ibidem.rs b/src/ibidem.rs index d65623d..afaf943 100644 --- a/src/ibidem.rs +++ b/src/ibidem.rs @@ -21,7 +21,7 @@ use crate::serde_tokenstream::spanned_error; /// it is not used in the context of [`from_tokenstream`]. /// /// [`from_tokenstream`]: crate::from_tokenstream -#[derive(Debug)] +#[derive(Clone, Debug, Default)] pub struct TokenStreamWrapper(TokenStream); impl TokenStreamWrapper { @@ -30,6 +30,12 @@ impl TokenStreamWrapper { } } +impl From for TokenStreamWrapper { + fn from(inner: TokenStream) -> Self { + Self(inner) + } +} + impl<'de> Deserialize<'de> for TokenStreamWrapper { fn deserialize(deserializer: D) -> Result where @@ -60,7 +66,7 @@ impl std::ops::Deref for TokenStreamWrapper { /// /// [`Parse`]: syn::parse::Parse /// [`from_tokenstream`]: crate::from_tokenstream -#[derive(Debug, Hash, Eq, PartialEq)] +#[derive(Clone, Debug, Default, Hash, Eq, PartialEq)] pub struct ParseWrapper(P); impl ParseWrapper

{ @@ -69,6 +75,12 @@ impl ParseWrapper

{ } } +impl From

for ParseWrapper

{ + fn from(inner: P) -> Self { + Self(inner) + } +} + impl<'de, P: syn::parse::Parse> Deserialize<'de> for ParseWrapper

{ fn deserialize(deserializer: D) -> Result where diff --git a/src/serde_tokenstream.rs b/src/serde_tokenstream.rs index 6663192..c4b5d97 100644 --- a/src/serde_tokenstream.rs +++ b/src/serde_tokenstream.rs @@ -2124,6 +2124,62 @@ mod tests { .unwrap(); } + #[test] + fn test_parse_wrapper_default_and_clone() { + fn default_ident() -> ParseWrapper { + ParseWrapper::from(syn::Ident::new( + "fallback", + proc_macro2::Span::call_site(), + )) + } + + #[derive(Deserialize, Clone)] + struct Input { + #[serde(default = "default_ident")] + ident: ParseWrapper, + } + + let input = from_tokenstream::("e! {}).unwrap(); + assert_eq!(*input.clone().ident, "fallback"); + + let input = + from_tokenstream::("e! { ident = given }).unwrap(); + assert_eq!(*input.ident, "given"); + + #[derive(Deserialize)] + struct Generic { + #[serde(default)] + generics: ParseWrapper, + } + + let input = from_tokenstream::("e! {}).unwrap(); + assert!(input.generics.params.is_empty()); + + let input = + from_tokenstream::("e! { generics = }) + .unwrap(); + assert_eq!(input.generics.params.len(), 1); + } + + #[test] + fn test_token_stream_wrapper_default_and_clone() { + #[derive(Deserialize, Clone)] + struct Input { + #[serde(default)] + tokens: TokenStreamWrapper, + } + + let input = from_tokenstream::("e! {}).unwrap(); + assert!(input.clone().tokens.is_empty()); + + let input = + from_tokenstream::("e! { tokens = a + b }).unwrap(); + assert_eq!(input.tokens.to_string(), "a + b"); + + let wrapper = TokenStreamWrapper::from(quote! { x }); + assert_eq!(wrapper.into_inner().to_string(), "x"); + } + #[test] fn parse_u128() { #[derive(Deserialize)]