Skip to main content

syn_serde/
item.rs

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