checked_rs_macro_impl/params/
derived_traits.rs1use 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}