1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum ConformanceFeature {
6 PathParamString,
8 PathParamInteger,
9 QueryParamString,
10 QueryParamInteger,
11 QueryParamArray,
12 HeaderParam,
13 CookieParam,
14 BodyJson,
16 BodyFormUrlencoded,
17 BodyMultipart,
18 SchemaString,
20 SchemaInteger,
21 SchemaNumber,
22 SchemaBoolean,
23 SchemaArray,
24 SchemaObject,
25 CompositionOneOf,
27 CompositionAnyOf,
28 CompositionAllOf,
29 FormatDate,
31 FormatDateTime,
32 FormatEmail,
33 FormatUuid,
34 FormatUri,
35 FormatIpv4,
36 FormatIpv6,
37 ConstraintRequired,
39 ConstraintOptional,
40 ConstraintMinMax,
41 ConstraintPattern,
42 ConstraintEnum,
43 Response200,
45 Response201,
46 Response204,
47 Response400,
48 Response404,
49 MethodGet,
51 MethodPost,
52 MethodPut,
53 MethodPatch,
54 MethodDelete,
55 MethodHead,
56 MethodOptions,
57 ContentNegotiation,
59 SecurityBearer,
61 SecurityApiKey,
62 SecurityBasic,
63}
64
65impl ConformanceFeature {
66 pub fn category(&self) -> &'static str {
68 match self {
69 Self::PathParamString
70 | Self::PathParamInteger
71 | Self::QueryParamString
72 | Self::QueryParamInteger
73 | Self::QueryParamArray
74 | Self::HeaderParam
75 | Self::CookieParam => "Parameters",
76 Self::BodyJson | Self::BodyFormUrlencoded | Self::BodyMultipart => "Request Bodies",
77 Self::SchemaString
78 | Self::SchemaInteger
79 | Self::SchemaNumber
80 | Self::SchemaBoolean
81 | Self::SchemaArray
82 | Self::SchemaObject => "Schema Types",
83 Self::CompositionOneOf | Self::CompositionAnyOf | Self::CompositionAllOf => {
84 "Composition"
85 }
86 Self::FormatDate
87 | Self::FormatDateTime
88 | Self::FormatEmail
89 | Self::FormatUuid
90 | Self::FormatUri
91 | Self::FormatIpv4
92 | Self::FormatIpv6 => "String Formats",
93 Self::ConstraintRequired
94 | Self::ConstraintOptional
95 | Self::ConstraintMinMax
96 | Self::ConstraintPattern
97 | Self::ConstraintEnum => "Constraints",
98 Self::Response200
99 | Self::Response201
100 | Self::Response204
101 | Self::Response400
102 | Self::Response404 => "Response Codes",
103 Self::MethodGet
104 | Self::MethodPost
105 | Self::MethodPut
106 | Self::MethodPatch
107 | Self::MethodDelete
108 | Self::MethodHead
109 | Self::MethodOptions => "HTTP Methods",
110 Self::ContentNegotiation => "Content Types",
111 Self::SecurityBearer | Self::SecurityApiKey | Self::SecurityBasic => "Security",
112 }
113 }
114
115 pub fn check_name(&self) -> &'static str {
117 match self {
118 Self::PathParamString => "param:path:string",
119 Self::PathParamInteger => "param:path:integer",
120 Self::QueryParamString => "param:query:string",
121 Self::QueryParamInteger => "param:query:integer",
122 Self::QueryParamArray => "param:query:array",
123 Self::HeaderParam => "param:header",
124 Self::CookieParam => "param:cookie",
125 Self::BodyJson => "body:json",
126 Self::BodyFormUrlencoded => "body:form-urlencoded",
127 Self::BodyMultipart => "body:multipart",
128 Self::SchemaString => "schema:string",
129 Self::SchemaInteger => "schema:integer",
130 Self::SchemaNumber => "schema:number",
131 Self::SchemaBoolean => "schema:boolean",
132 Self::SchemaArray => "schema:array",
133 Self::SchemaObject => "schema:object",
134 Self::CompositionOneOf => "composition:oneOf",
135 Self::CompositionAnyOf => "composition:anyOf",
136 Self::CompositionAllOf => "composition:allOf",
137 Self::FormatDate => "format:date",
138 Self::FormatDateTime => "format:date-time",
139 Self::FormatEmail => "format:email",
140 Self::FormatUuid => "format:uuid",
141 Self::FormatUri => "format:uri",
142 Self::FormatIpv4 => "format:ipv4",
143 Self::FormatIpv6 => "format:ipv6",
144 Self::ConstraintRequired => "constraint:required",
145 Self::ConstraintOptional => "constraint:optional",
146 Self::ConstraintMinMax => "constraint:minmax",
147 Self::ConstraintPattern => "constraint:pattern",
148 Self::ConstraintEnum => "constraint:enum",
149 Self::Response200 => "response:200",
150 Self::Response201 => "response:201",
151 Self::Response204 => "response:204",
152 Self::Response400 => "response:400",
153 Self::Response404 => "response:404",
154 Self::MethodGet => "method:GET",
155 Self::MethodPost => "method:POST",
156 Self::MethodPut => "method:PUT",
157 Self::MethodPatch => "method:PATCH",
158 Self::MethodDelete => "method:DELETE",
159 Self::MethodHead => "method:HEAD",
160 Self::MethodOptions => "method:OPTIONS",
161 Self::ContentNegotiation => "content:negotiation",
162 Self::SecurityBearer => "security:bearer",
163 Self::SecurityApiKey => "security:apikey",
164 Self::SecurityBasic => "security:basic",
165 }
166 }
167
168 pub fn all() -> &'static [ConformanceFeature] {
170 &[
171 Self::PathParamString,
172 Self::PathParamInteger,
173 Self::QueryParamString,
174 Self::QueryParamInteger,
175 Self::QueryParamArray,
176 Self::HeaderParam,
177 Self::CookieParam,
178 Self::BodyJson,
179 Self::BodyFormUrlencoded,
180 Self::BodyMultipart,
181 Self::SchemaString,
182 Self::SchemaInteger,
183 Self::SchemaNumber,
184 Self::SchemaBoolean,
185 Self::SchemaArray,
186 Self::SchemaObject,
187 Self::CompositionOneOf,
188 Self::CompositionAnyOf,
189 Self::CompositionAllOf,
190 Self::FormatDate,
191 Self::FormatDateTime,
192 Self::FormatEmail,
193 Self::FormatUuid,
194 Self::FormatUri,
195 Self::FormatIpv4,
196 Self::FormatIpv6,
197 Self::ConstraintRequired,
198 Self::ConstraintOptional,
199 Self::ConstraintMinMax,
200 Self::ConstraintPattern,
201 Self::ConstraintEnum,
202 Self::Response200,
203 Self::Response201,
204 Self::Response204,
205 Self::Response400,
206 Self::Response404,
207 Self::MethodGet,
208 Self::MethodPost,
209 Self::MethodPut,
210 Self::MethodPatch,
211 Self::MethodDelete,
212 Self::MethodHead,
213 Self::MethodOptions,
214 Self::ContentNegotiation,
215 Self::SecurityBearer,
216 Self::SecurityApiKey,
217 Self::SecurityBasic,
218 ]
219 }
220
221 pub fn categories() -> &'static [&'static str] {
223 &[
224 "Parameters",
225 "Request Bodies",
226 "Schema Types",
227 "Composition",
228 "String Formats",
229 "Constraints",
230 "Response Codes",
231 "HTTP Methods",
232 "Content Types",
233 "Security",
234 ]
235 }
236}
237
238#[cfg(test)]
239mod tests {
240 use super::*;
241
242 #[test]
243 fn test_all_features_have_categories() {
244 for feature in ConformanceFeature::all() {
245 assert!(!feature.category().is_empty());
246 assert!(!feature.check_name().is_empty());
247 }
248 }
249
250 #[test]
251 fn test_all_categories_covered() {
252 let categories: std::collections::HashSet<&str> =
253 ConformanceFeature::all().iter().map(|f| f.category()).collect();
254 for cat in ConformanceFeature::categories() {
255 assert!(categories.contains(cat), "Category '{}' has no features", cat);
256 }
257 }
258}