syn_serde/
item.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3use super::*;
4#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
5pub use crate::{
6    ast_enum::{
7        FnArg, ForeignItem, ImplItem, ImplRestriction, Item, StaticMutability, TraitItem, UseTree,
8    },
9    ast_struct::{
10        ForeignItemFn, ForeignItemMacro, ForeignItemStatic, ForeignItemType, ImplItemConst,
11        ImplItemFn, ImplItemMacro, ImplItemType, ItemConst, ItemEnum, ItemExternCrate, ItemFn,
12        ItemForeignMod, ItemImpl, ItemMacro, ItemStatic, ItemTrait, ItemTraitAlias, ItemType,
13        ItemUnion, ItemUse, Signature, TraitItemConst, TraitItemMacro, TraitItemType, UseGroup,
14        UseName, UsePath, UseRename, Variadic,
15    },
16};
17
18ast_struct! {
19    /// An adapter for [`struct@syn::ItemMod`].
20    pub struct ItemMod {
21        #[serde(default, skip_serializing_if = "Vec::is_empty")]
22        pub(crate) attrs: Vec<Attribute>,
23        #[serde(default, skip_serializing_if = "Visibility::is_inherited")]
24        pub(crate) vis: Visibility,
25        #[serde(rename = "unsafe")]
26        #[serde(default, skip_serializing_if = "not")]
27        pub(crate) unsafety: bool,
28        pub(crate) ident: Ident,
29        // TODO: should not skip_serializing_if
30        #[serde(default, skip_serializing_if = "Option::is_none")]
31        pub(crate) content: Option<Vec<Item>>,
32        // TODO: can remove
33        #[serde(default, skip_serializing_if = "not")]
34        pub(crate) semi: bool,
35    }
36}
37
38ast_struct! {
39    /// An adapter for [`struct@syn::ItemStruct`].
40    pub struct ItemStruct {
41        #[serde(default, skip_serializing_if = "Vec::is_empty")]
42        pub(crate) attrs: Vec<Attribute>,
43        #[serde(default, skip_serializing_if = "Visibility::is_inherited")]
44        pub(crate) vis: Visibility,
45        pub(crate) ident: Ident,
46        #[serde(default, skip_serializing_if = "Generics::is_none")]
47        pub(crate) generics: Generics,
48        pub(crate) fields: Fields,
49        // #[serde(default, skip_serializing_if = "not")]
50        // pub(crate) semi_token: bool,
51    }
52}
53
54ast_struct! {
55    /// An adapter for [`struct@syn::TraitItemFn`].
56    pub struct TraitItemFn {
57        #[serde(default, skip_serializing_if = "Vec::is_empty")]
58        pub(crate) attrs: Vec<Attribute>,
59        #[serde(flatten)]
60        pub(crate) sig: Signature,
61        #[serde(default, skip_serializing_if = "Option::is_none")]
62        pub(crate) default: Option<Block>,
63        // #[serde(default, skip_serializing_if = "not")]
64        // pub(crate) semi_token: bool,
65    }
66}
67
68ast_struct! {
69    /// An adapter for [`struct@syn::Receiver`].
70    pub struct Receiver {
71        #[serde(default, skip_serializing_if = "Vec::is_empty")]
72        pub(crate) attrs: Vec<Attribute>,
73        #[serde(rename = "ref")]
74        #[serde(default, skip_serializing_if = "not")]
75        pub(crate) reference: bool,
76        #[serde(default, skip_serializing_if = "Option::is_none")]
77        pub(crate) lifetime: Option<Lifetime>,
78        #[serde(rename = "mut")]
79        #[serde(default, skip_serializing_if = "not")]
80        pub(crate) mutability: bool,
81        #[serde(default, skip_serializing_if = "not")]
82        pub(crate) colon_token: bool,
83        // TODO: skip if colon_token=false?
84        pub(crate) ty: Box<Type>,
85    }
86}
87
88impl StaticMutability {
89    pub(crate) fn is_none(&self) -> bool {
90        matches!(self, Self::None)
91    }
92}
93impl Default for StaticMutability {
94    fn default() -> Self {
95        Self::None
96    }
97}
98
99mod convert {
100    use super::*;
101
102    // ItemStruct
103    syn_trait_impl!(syn::ItemStruct);
104    impl From<&syn::ItemStruct> for ItemStruct {
105        fn from(other: &syn::ItemStruct) -> Self {
106            let fields: Fields = other.fields.ref_into();
107            assert_struct_semi(&fields, other.semi_token.is_some());
108
109            Self {
110                attrs: other.attrs.map_into(),
111                vis: other.vis.ref_into(),
112                ident: other.ident.ref_into(),
113                generics: other.generics.ref_into(),
114                fields,
115            }
116        }
117    }
118    impl From<&ItemStruct> for syn::ItemStruct {
119        fn from(other: &ItemStruct) -> Self {
120            Self {
121                attrs: other.attrs.map_into(),
122                vis: other.vis.ref_into(),
123                struct_token: default(),
124                ident: other.ident.ref_into(),
125                generics: other.generics.ref_into(),
126                fields: other.fields.ref_into(),
127                semi_token: default_or_none(!other.fields.is_named()),
128            }
129        }
130    }
131
132    // TraitItemFn
133    syn_trait_impl!(syn::TraitItemFn);
134    impl From<&syn::TraitItemFn> for TraitItemFn {
135        fn from(other: &syn::TraitItemFn) -> Self {
136            if other.default.is_some() {
137                // `fn foo() -> bool {};`
138                assert!(other.semi_token.is_none(), "unexpected token: `;`");
139            } else {
140                // `fn foo() -> bool`
141                assert!(other.semi_token.is_some(), "expected `;`");
142            }
143
144            Self {
145                attrs: other.attrs.map_into(),
146                sig: other.sig.ref_into(),
147                default: other.default.map_into(),
148            }
149        }
150    }
151    impl From<&TraitItemFn> for syn::TraitItemFn {
152        fn from(other: &TraitItemFn) -> Self {
153            Self {
154                attrs: other.attrs.map_into(),
155                sig: other.sig.ref_into(),
156                default: other.default.map_into(),
157                semi_token: default_or_none(other.default.is_none()),
158            }
159        }
160    }
161
162    // Receiver
163    syn_trait_impl!(syn::Receiver);
164    impl From<&syn::Receiver> for Receiver {
165        fn from(node: &syn::Receiver) -> Self {
166            Self {
167                attrs: node.attrs.map_into(),
168                reference: node.reference.is_some(),
169                lifetime: node.reference.as_ref().and_then(|(_0, _1)| _1.map_into()),
170                mutability: node.mutability.is_some(),
171                colon_token: node.colon_token.is_some(),
172                ty: node.ty.map_into(),
173            }
174        }
175    }
176    impl From<&Receiver> for syn::Receiver {
177        fn from(node: &Receiver) -> Self {
178            Self {
179                attrs: node.attrs.map_into(),
180                reference: if node.reference {
181                    Some((default(), node.lifetime.map_into()))
182                } else {
183                    None
184                },
185                mutability: default_or_none(node.mutability),
186                self_token: default(),
187                colon_token: default_or_none(node.colon_token),
188                ty: node.ty.map_into(),
189            }
190        }
191    }
192}