utoipa_gen/component/schema/
features.rs1use syn::{
2 parse::{Parse, ParseBuffer, ParseStream},
3 Attribute,
4};
5
6use crate::{
7 component::features::{
8 impl_into_inner, impl_merge, parse_features, AdditionalProperties, As, Default, Deprecated,
9 Example, ExclusiveMaximum, ExclusiveMinimum, Feature, Format, Inline, IntoInner, MaxItems,
10 MaxLength, MaxProperties, Maximum, Merge, MinItems, MinLength, MinProperties, Minimum,
11 MultipleOf, Nullable, Pattern, ReadOnly, Rename, RenameAll, Required, SchemaWith, Title,
12 ValueType, WriteOnly, XmlAttr,
13 },
14 ResultExt,
15};
16
17#[cfg_attr(feature = "debug", derive(Debug))]
18pub struct NamedFieldStructFeatures(Vec<Feature>);
19
20impl Parse for NamedFieldStructFeatures {
21 fn parse(input: ParseStream) -> syn::Result<Self> {
22 Ok(NamedFieldStructFeatures(parse_features!(
23 input as Example,
24 XmlAttr,
25 Title,
26 RenameAll,
27 MaxProperties,
28 MinProperties,
29 As,
30 Default,
31 Deprecated
32 )))
33 }
34}
35
36impl_into_inner!(NamedFieldStructFeatures);
37
38#[cfg_attr(feature = "debug", derive(Debug))]
39pub struct UnnamedFieldStructFeatures(Vec<Feature>);
40
41impl Parse for UnnamedFieldStructFeatures {
42 fn parse(input: ParseStream) -> syn::Result<Self> {
43 Ok(UnnamedFieldStructFeatures(parse_features!(
44 input as Example,
45 Default,
46 Title,
47 Format,
48 ValueType,
49 As,
50 Deprecated
51 )))
52 }
53}
54
55impl_into_inner!(UnnamedFieldStructFeatures);
56
57pub struct EnumFeatures(Vec<Feature>);
58
59impl Parse for EnumFeatures {
60 fn parse(input: ParseStream) -> syn::Result<Self> {
61 Ok(EnumFeatures(parse_features!(
62 input as Example,
63 Default,
64 Title,
65 RenameAll,
66 As,
67 Deprecated
68 )))
69 }
70}
71
72impl_into_inner!(EnumFeatures);
73
74pub struct ComplexEnumFeatures(Vec<Feature>);
75
76impl Parse for ComplexEnumFeatures {
77 fn parse(input: ParseStream) -> syn::Result<Self> {
78 Ok(ComplexEnumFeatures(parse_features!(
79 input as Example,
80 Default,
81 RenameAll,
82 As,
83 Deprecated
84 )))
85 }
86}
87
88impl_into_inner!(ComplexEnumFeatures);
89
90pub struct NamedFieldFeatures(Vec<Feature>);
91
92impl Parse for NamedFieldFeatures {
93 fn parse(input: ParseStream) -> syn::Result<Self> {
94 Ok(NamedFieldFeatures(parse_features!(
95 input as Example,
96 ValueType,
97 Format,
98 Default,
99 WriteOnly,
100 ReadOnly,
101 XmlAttr,
102 Inline,
103 Nullable,
104 Rename,
105 MultipleOf,
106 Maximum,
107 Minimum,
108 ExclusiveMaximum,
109 ExclusiveMinimum,
110 MaxLength,
111 MinLength,
112 Pattern,
113 MaxItems,
114 MinItems,
115 SchemaWith,
116 AdditionalProperties,
117 Required,
118 Deprecated
119 )))
120 }
121}
122
123impl_into_inner!(NamedFieldFeatures);
124
125pub struct EnumNamedFieldVariantFeatures(Vec<Feature>);
126
127impl Parse for EnumNamedFieldVariantFeatures {
128 fn parse(input: ParseStream) -> syn::Result<Self> {
129 Ok(EnumNamedFieldVariantFeatures(parse_features!(
130 input as Example,
131 XmlAttr,
132 Title,
133 Rename,
134 RenameAll,
135 Deprecated
136 )))
137 }
138}
139
140impl_into_inner!(EnumNamedFieldVariantFeatures);
141
142pub struct EnumUnnamedFieldVariantFeatures(Vec<Feature>);
143
144impl Parse for EnumUnnamedFieldVariantFeatures {
145 fn parse(input: ParseStream) -> syn::Result<Self> {
146 Ok(EnumUnnamedFieldVariantFeatures(parse_features!(
147 input as Example,
148 Default,
149 Title,
150 Format,
151 ValueType,
152 Rename,
153 Deprecated
154 )))
155 }
156}
157
158impl_into_inner!(EnumUnnamedFieldVariantFeatures);
159
160pub trait FromAttributes {
161 fn parse_features<T>(&self) -> Option<T>
162 where
163 T: Parse + Merge<T>;
164}
165
166impl FromAttributes for &'_ [Attribute] {
167 fn parse_features<T>(&self) -> Option<T>
168 where
169 T: Parse + Merge<T>,
170 {
171 parse_schema_features::<T>(self)
172 }
173}
174
175impl FromAttributes for Vec<Attribute> {
176 fn parse_features<T>(&self) -> Option<T>
177 where
178 T: Parse + Merge<T>,
179 {
180 parse_schema_features::<T>(self)
181 }
182}
183
184impl_merge!(
185 NamedFieldStructFeatures,
186 UnnamedFieldStructFeatures,
187 EnumFeatures,
188 ComplexEnumFeatures,
189 NamedFieldFeatures,
190 EnumNamedFieldVariantFeatures,
191 EnumUnnamedFieldVariantFeatures
192);
193
194pub fn parse_schema_features<T: Sized + Parse + Merge<T>>(attributes: &[Attribute]) -> Option<T> {
195 attributes
196 .iter()
197 .filter(|attribute| {
198 attribute
199 .path()
200 .get_ident()
201 .map(|ident| *ident == "schema")
202 .unwrap_or(false)
203 })
204 .map(|attribute| attribute.parse_args::<T>().unwrap_or_abort())
205 .reduce(|acc, item| acc.merge(item))
206}
207
208pub fn parse_schema_features_with<
209 T: Merge<T>,
210 P: for<'r> FnOnce(&'r ParseBuffer<'r>) -> syn::Result<T> + Copy,
211>(
212 attributes: &[Attribute],
213 parser: P,
214) -> Option<T> {
215 attributes
216 .iter()
217 .filter(|attribute| {
218 attribute
219 .path()
220 .get_ident()
221 .map(|ident| *ident == "schema")
222 .unwrap_or(false)
223 })
224 .map(|attributes| attributes.parse_args_with(parser).unwrap_or_abort())
225 .reduce(|acc, item| acc.merge(item))
226}