1use proc_macro2::Span;
4use sealed::sealed;
5use syn::{punctuated::Punctuated, token};
6
7#[sealed]
9pub trait Data {
10 fn named_fields(self) -> syn::Result<Punctuated<syn::Field, token::Comma>>;
19
20 fn named_fields_ref(
29 &self,
30 ) -> syn::Result<&Punctuated<syn::Field, token::Comma>>;
31
32 fn unnamed_fields(
41 self,
42 ) -> syn::Result<Punctuated<syn::Field, token::Comma>>;
43
44 fn unnamed_fields_ref(
53 &self,
54 ) -> syn::Result<&Punctuated<syn::Field, token::Comma>>;
55}
56
57#[sealed]
58impl Data for syn::Data {
59 fn named_fields(self) -> syn::Result<Punctuated<syn::Field, token::Comma>> {
60 match self {
61 Self::Struct(data) => match data.fields {
62 syn::Fields::Named(f) => Ok(f.named),
63 syn::Fields::Unit | syn::Fields::Unnamed(_) => {
64 Err(syn::Error::new_spanned(
65 &data.fields,
66 "expected named struct fields only",
67 ))
68 }
69 },
70 Self::Enum(data) => Err(syn::Error::new_spanned(
71 data.enum_token,
72 "expected struct only",
73 )),
74 Self::Union(data) => Err(syn::Error::new_spanned(
75 data.union_token,
76 "expected struct only",
77 )),
78 }
79 }
80
81 fn named_fields_ref(
82 &self,
83 ) -> syn::Result<&Punctuated<syn::Field, token::Comma>> {
84 match self {
85 Self::Struct(data) => match &data.fields {
86 syn::Fields::Named(f) => Ok(&f.named),
87 syn::Fields::Unit | syn::Fields::Unnamed(_) => {
88 Err(syn::Error::new_spanned(
89 &data.fields,
90 "expected named struct fields only",
91 ))
92 }
93 },
94 Self::Enum(data) => Err(syn::Error::new_spanned(
95 data.enum_token,
96 "expected struct only",
97 )),
98 Self::Union(data) => Err(syn::Error::new_spanned(
99 data.union_token,
100 "expected struct only",
101 )),
102 }
103 }
104
105 fn unnamed_fields(
106 self,
107 ) -> syn::Result<Punctuated<syn::Field, token::Comma>> {
108 match self {
109 Self::Struct(data) => match data.fields {
110 syn::Fields::Unnamed(f) => Ok(f.unnamed),
111 syn::Fields::Unit | syn::Fields::Named(_) => {
112 Err(syn::Error::new_spanned(
113 &data.fields,
114 "expected unnamed struct fields only",
115 ))
116 }
117 },
118 Self::Enum(data) => Err(syn::Error::new_spanned(
119 data.enum_token,
120 "expected struct only",
121 )),
122 Self::Union(data) => Err(syn::Error::new_spanned(
123 data.union_token,
124 "expected struct only",
125 )),
126 }
127 }
128
129 fn unnamed_fields_ref(
130 &self,
131 ) -> syn::Result<&Punctuated<syn::Field, token::Comma>> {
132 match self {
133 Self::Struct(data) => match &data.fields {
134 syn::Fields::Unnamed(f) => Ok(&f.unnamed),
135 syn::Fields::Unit | syn::Fields::Named(_) => {
136 Err(syn::Error::new_spanned(
137 &data.fields,
138 "expected unnamed struct fields only",
139 ))
140 }
141 },
142 Self::Enum(data) => Err(syn::Error::new_spanned(
143 data.enum_token,
144 "expected struct only",
145 )),
146 Self::Union(data) => Err(syn::Error::new_spanned(
147 data.union_token,
148 "expected struct only",
149 )),
150 }
151 }
152}
153
154#[sealed]
156pub trait Ident {
157 #[must_use]
162 fn new_on_call_site(ident: &str) -> syn::Ident;
163}
164
165#[sealed]
166impl Ident for syn::Ident {
167 #[inline]
168 fn new_on_call_site(string: &str) -> Self {
169 Self::new(string, Span::call_site())
170 }
171}