Skip to main content

syn_serde/
generics.rs

1// SPDX-License-Identifier: Apache-2.0 OR MIT
2
3use super::*;
4pub use crate::{
5    ast_enum::{GenericParam, TraitBoundModifier, TypeParamBound, WherePredicate},
6    ast_struct::{
7        BoundLifetimes, ConstParam, LifetimeParam, PredicateLifetime, TraitBound, TypeParam,
8        WhereClause,
9    },
10};
11
12ast_struct! {
13    /// An adapter for [`struct@syn::Generics`].
14    #[derive(Default)]
15    pub struct Generics {
16        // #[serde(default, skip_serializing_if = "not")]
17        // pub(crate) lt_token: bool,
18        #[serde(default, skip_serializing_if = "Punctuated::is_empty")]
19        pub(crate) params: Punctuated<GenericParam>,
20        // #[serde(default, skip_serializing_if = "not")]
21        // pub(crate) gt_token: bool,
22        #[serde(default, skip_serializing_if = "Option::is_none")]
23        pub(crate) where_clause: Option<WhereClause>,
24    }
25}
26
27impl Generics {
28    pub(crate) fn is_none(&self) -> bool {
29        self.params.is_empty() && self.where_clause.is_none() // && !self.lt_token && !self.gt_token
30    }
31}
32
33impl TraitBoundModifier {
34    pub(crate) fn is_none(&self) -> bool {
35        match self {
36            TraitBoundModifier::None => true,
37            TraitBoundModifier::Maybe => false,
38        }
39    }
40}
41
42impl Default for TraitBoundModifier {
43    fn default() -> Self {
44        TraitBoundModifier::None
45    }
46}
47
48ast_struct! {
49    /// An adapter for [`struct@syn::PredicateType`].
50    pub struct PredicateType {
51        #[serde(default, skip_serializing_if = "Option::is_none")]
52        pub(crate) lifetimes: Option<BoundLifetimes>,
53        pub(crate) bounded_ty: Type,
54        // TODO: should allow default?
55        // #[serde(default, skip_serializing_if = "Punctuated::is_empty")]
56        pub(crate) bounds: Punctuated<TypeParamBound>,
57    }
58}
59
60mod convert {
61    use super::*;
62
63    // Generics
64    syn_trait_impl!(syn::Generics);
65    impl From<&syn::Generics> for Generics {
66        fn from(other: &syn::Generics) -> Self {
67            // `ident ..>` or `ident <..`
68            assert_eq!(other.lt_token.is_some(), other.gt_token.is_some());
69            // `ident T`
70            assert!(other.params.is_empty() || other.lt_token.is_some(), "expected `<`");
71
72            Self { params: other.params.map_into(), where_clause: other.where_clause.map_into() }
73        }
74    }
75    impl From<&Generics> for syn::Generics {
76        fn from(other: &Generics) -> Self {
77            Self {
78                lt_token: default_or_none(!other.params.is_empty()),
79                params: other.params.map_into(),
80                gt_token: default_or_none(!other.params.is_empty()),
81                where_clause: other.where_clause.map_into(),
82            }
83        }
84    }
85}