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