checked_rs_macro_impl/params/
derived_traits.rs

1use proc_macro2::TokenStream;
2use quote::{quote, ToTokens};
3use syn::{parenthesized, parse::Parse};
4
5use super::kw;
6
7#[derive(Clone)]
8pub struct DerivedTraits {
9    pub derive_kw: kw::derive,
10    pub paren: syn::token::Paren,
11    pub traits: syn::punctuated::Punctuated<syn::TypePath, syn::Token![,]>,
12}
13
14impl Parse for DerivedTraits {
15    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
16        let derive_kw = input.parse()?;
17
18        let content;
19        parenthesized!(content in input);
20
21        Ok(Self {
22            derive_kw,
23            paren: syn::token::Paren::default(),
24            traits: content.parse_terminated(syn::TypePath::parse, syn::Token![,])?,
25        })
26    }
27}
28
29impl ToTokens for DerivedTraits {
30    fn to_tokens(&self, tokens: &mut TokenStream) {
31        let traits = &self.traits;
32        tokens.extend(quote! {
33            #[derive(#traits)]
34        });
35    }
36}
37
38impl std::fmt::Debug for DerivedTraits {
39    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
40        let traits = self
41            .traits
42            .iter()
43            .map(|trait_| trait_.to_token_stream())
44            .collect::<Vec<_>>();
45
46        f.debug_struct("DerivedTraits")
47            .field("traits", &traits)
48            .finish_non_exhaustive()
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55    use crate::{assert_parse, snapshot};
56
57    #[test]
58    fn parse_derive_traits() {
59        assert_parse!(DerivedTraits => { derive(Debug) });
60    }
61
62    #[test]
63    fn snapshot_derive_traits() {
64        snapshot!(DerivedTraits => { derive(Debug) });
65    }
66}