Skip to main content

wae_schema/
lib.rs

1//! WAE Schema - Schema 定义与验证模块
2//!
3//! 提供统一的 Schema 定义能力,支持:
4//! - 数据结构 Schema 定义
5//! - Schema 验证
6//! - OpenAPI 文档生成
7#![warn(missing_docs)]
8
9use serde::{Deserialize, Serialize};
10
11/// OpenAPI 相关功能
12pub mod openapi;
13/// Swagger UI 相关功能
14pub mod swagger_ui;
15use serde_json;
16
17#[cfg(feature = "yaml")]
18use serde_yaml;
19
20/// Schema 生成 trait
21///
22/// 实现此 trait 的类型可以自动生成 OpenAPI Schema。
23pub trait ToSchema {
24    /// 生成 Schema 定义
25    fn schema() -> Schema;
26}
27
28/// Schema 类型定义
29#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
30#[serde(rename_all = "lowercase")]
31pub enum SchemaType {
32    /// 字符串类型
33    String,
34    /// 整数类型
35    Integer,
36    /// 浮点数类型
37    Number,
38    /// 布尔类型
39    Boolean,
40    /// 数组类型
41    Array,
42    /// 对象类型
43    Object,
44    /// 空值类型
45    Null,
46}
47
48impl Default for SchemaType {
49    /// 创建默认的 Schema 类型(Object)
50    fn default() -> Self {
51        Self::Object
52    }
53}
54
55/// Schema 定义
56#[derive(Debug, Clone, Serialize, Deserialize)]
57pub struct Schema {
58    /// Schema 标题
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub title: Option<String>,
61    /// Schema 描述
62    #[serde(skip_serializing_if = "Option::is_none")]
63    pub description: Option<String>,
64    /// Schema 类型
65    #[serde(rename = "type")]
66    pub schema_type: SchemaType,
67    /// 属性定义(仅 Object 类型)
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub properties: Option<std::collections::BTreeMap<String, Schema>>,
70    /// 必需属性列表
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub required: Option<Vec<String>>,
73    /// 数组元素类型(仅 Array 类型)
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub items: Option<Box<Schema>>,
76    /// 枚举值
77    #[serde(rename = "enum")]
78    #[serde(skip_serializing_if = "Option::is_none")]
79    pub enum_values: Option<Vec<serde_json::Value>>,
80    /// 默认值
81    #[serde(skip_serializing_if = "Option::is_none")]
82    pub default: Option<serde_json::Value>,
83    /// 示例值
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub example: Option<serde_json::Value>,
86    /// 是否可为空
87    #[serde(default)]
88    pub nullable: bool,
89    /// 只读
90    #[serde(default)]
91    pub read_only: bool,
92    /// 只写
93    #[serde(default)]
94    pub write_only: bool,
95    /// 最小值(Number/Integer)
96    #[serde(skip_serializing_if = "Option::is_none")]
97    pub minimum: Option<f64>,
98    /// 最大值(Number/Integer)
99    #[serde(skip_serializing_if = "Option::is_none")]
100    pub maximum: Option<f64>,
101    /// 最小长度(String)
102    #[serde(skip_serializing_if = "Option::is_none")]
103    pub min_length: Option<usize>,
104    /// 最大长度(String)
105    #[serde(skip_serializing_if = "Option::is_none")]
106    pub max_length: Option<usize>,
107    /// 正则模式(String)
108    #[serde(skip_serializing_if = "Option::is_none")]
109    pub pattern: Option<String>,
110    /// 格式(String)
111    #[serde(skip_serializing_if = "Option::is_none")]
112    pub format: Option<String>,
113    /// 多个类型(用于 oneOf)
114    #[serde(rename = "oneOf")]
115    #[serde(skip_serializing_if = "Option::is_none")]
116    pub one_of: Option<Vec<Schema>>,
117    /// 多个类型(用于 anyOf)
118    #[serde(rename = "anyOf")]
119    #[serde(skip_serializing_if = "Option::is_none")]
120    pub any_of: Option<Vec<Schema>>,
121    /// 多个类型(用于 allOf)
122    #[serde(rename = "allOf")]
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub all_of: Option<Vec<Schema>>,
125}
126
127impl Default for Schema {
128    /// 创建默认的 Schema(Object 类型)
129    fn default() -> Self {
130        Self {
131            title: None,
132            description: None,
133            schema_type: SchemaType::Object,
134            properties: None,
135            required: None,
136            items: None,
137            enum_values: None,
138            default: None,
139            example: None,
140            nullable: false,
141            read_only: false,
142            write_only: false,
143            minimum: None,
144            maximum: None,
145            min_length: None,
146            max_length: None,
147            pattern: None,
148            format: None,
149            one_of: None,
150            any_of: None,
151            all_of: None,
152        }
153    }
154}
155
156impl Schema {
157    /// 创建字符串 Schema
158    pub fn string() -> Self {
159        Self { schema_type: SchemaType::String, ..Default::default() }
160    }
161
162    /// 创建整数 Schema
163    pub fn integer() -> Self {
164        Self { schema_type: SchemaType::Integer, ..Default::default() }
165    }
166
167    /// 创建数字 Schema
168    pub fn number() -> Self {
169        Self { schema_type: SchemaType::Number, ..Default::default() }
170    }
171
172    /// 创建布尔 Schema
173    pub fn boolean() -> Self {
174        Self { schema_type: SchemaType::Boolean, ..Default::default() }
175    }
176
177    /// 创建数组 Schema
178    pub fn array(items: Schema) -> Self {
179        Self { schema_type: SchemaType::Array, items: Some(Box::new(items)), ..Default::default() }
180    }
181
182    /// 创建对象 Schema
183    pub fn object() -> Self {
184        Self { schema_type: SchemaType::Object, properties: Some(std::collections::BTreeMap::new()), ..Default::default() }
185    }
186
187    /// 设置标题
188    pub fn title(mut self, title: impl Into<String>) -> Self {
189        self.title = Some(title.into());
190        self
191    }
192
193    /// 设置描述
194    pub fn description(mut self, desc: impl Into<String>) -> Self {
195        self.description = Some(desc.into());
196        self
197    }
198
199    /// 添加属性
200    pub fn property(mut self, name: impl Into<String>, schema: Schema) -> Self {
201        let properties = self.properties.get_or_insert_with(std::collections::BTreeMap::new);
202        properties.insert(name.into(), schema);
203        self
204    }
205
206    /// 设置必需属性
207    pub fn required(mut self, fields: Vec<&str>) -> Self {
208        self.required = Some(fields.into_iter().map(String::from).collect());
209        self
210    }
211
212    /// 设置枚举值
213    pub fn enum_values(mut self, values: Vec<serde_json::Value>) -> Self {
214        self.enum_values = Some(values);
215        self
216    }
217
218    /// 设置默认值
219    pub fn with_default(mut self, value: serde_json::Value) -> Self {
220        self.default = Some(value);
221        self
222    }
223
224    /// 设置示例值
225    pub fn example(mut self, value: serde_json::Value) -> Self {
226        self.example = Some(value);
227        self
228    }
229
230    /// 设置格式
231    pub fn format(mut self, format: impl Into<String>) -> Self {
232        self.format = Some(format.into());
233        self
234    }
235
236    /// 设置最小长度
237    pub fn min_length(mut self, len: usize) -> Self {
238        self.min_length = Some(len);
239        self
240    }
241
242    /// 设置最大长度
243    pub fn max_length(mut self, len: usize) -> Self {
244        self.max_length = Some(len);
245        self
246    }
247
248    /// 设置最小值
249    pub fn minimum(mut self, min: f64) -> Self {
250        self.minimum = Some(min);
251        self
252    }
253
254    /// 设置最大值
255    pub fn maximum(mut self, max: f64) -> Self {
256        self.maximum = Some(max);
257        self
258    }
259
260    /// 设置可为空
261    pub fn nullable(mut self, nullable: bool) -> Self {
262        self.nullable = nullable;
263        self
264    }
265
266    /// 设置只读
267    pub fn read_only(mut self, read_only: bool) -> Self {
268        self.read_only = read_only;
269        self
270    }
271
272    /// 设置只写
273    pub fn write_only(mut self, write_only: bool) -> Self {
274        self.write_only = write_only;
275        self
276    }
277
278    /// 设置 oneOf
279    pub fn one_of(mut self, schemas: Vec<Schema>) -> Self {
280        self.one_of = Some(schemas);
281        self
282    }
283
284    /// 设置 anyOf
285    pub fn any_of(mut self, schemas: Vec<Schema>) -> Self {
286        self.any_of = Some(schemas);
287        self
288    }
289
290    /// 设置 allOf
291    pub fn all_of(mut self, schemas: Vec<Schema>) -> Self {
292        self.all_of = Some(schemas);
293        self
294    }
295
296    /// 转换为 JSON Schema
297    pub fn to_json_schema(&self) -> serde_json::Value {
298        serde_json::to_value(self).unwrap_or(serde_json::Value::Null)
299    }
300}
301
302/// Schema 构建器
303pub struct SchemaBuilder {
304    schema: Schema,
305}
306
307impl SchemaBuilder {
308    /// 创建新的构建器
309    pub fn new() -> Self {
310        Self { schema: <Schema as Default>::default() }
311    }
312
313    /// 创建字符串构建器
314    pub fn string() -> Self {
315        Self { schema: Schema::string() }
316    }
317
318    /// 创建整数构建器
319    pub fn integer() -> Self {
320        Self { schema: Schema::integer() }
321    }
322
323    /// 创建数字构建器
324    pub fn number() -> Self {
325        Self { schema: Schema::number() }
326    }
327
328    /// 创建布尔构建器
329    pub fn boolean() -> Self {
330        Self { schema: Schema::boolean() }
331    }
332
333    /// 创建数组构建器
334    pub fn array(items: Schema) -> Self {
335        Self { schema: Schema::array(items) }
336    }
337
338    /// 创建对象构建器
339    pub fn object() -> Self {
340        Self { schema: Schema::object() }
341    }
342
343    /// 设置标题
344    pub fn title(mut self, title: impl Into<String>) -> Self {
345        self.schema.title = Some(title.into());
346        self
347    }
348
349    /// 设置描述
350    pub fn description(mut self, desc: impl Into<String>) -> Self {
351        self.schema.description = Some(desc.into());
352        self
353    }
354
355    /// 添加属性
356    pub fn property(mut self, name: impl Into<String>, schema: Schema) -> Self {
357        let properties = self.schema.properties.get_or_insert_with(std::collections::BTreeMap::new);
358        properties.insert(name.into(), schema);
359        self
360    }
361
362    /// 设置必需属性
363    pub fn required(mut self, fields: Vec<&str>) -> Self {
364        self.schema.required = Some(fields.into_iter().map(String::from).collect());
365        self
366    }
367
368    /// 构建 Schema
369    pub fn build(self) -> Schema {
370        self.schema
371    }
372}
373
374impl Default for SchemaBuilder {
375    /// 创建默认的 Schema 构建器
376    fn default() -> Self {
377        Self::new()
378    }
379}
380
381/// OpenAPI 文档信息
382#[derive(Debug, Clone, Serialize, Deserialize)]
383pub struct OpenApiInfo {
384    /// API 标题
385    pub title: String,
386    /// API 版本
387    pub version: String,
388    /// API 描述
389    #[serde(skip_serializing_if = "Option::is_none")]
390    pub description: Option<String>,
391    /// 服务条款 URL
392    #[serde(skip_serializing_if = "Option::is_none")]
393    pub terms_of_service: Option<String>,
394    /// 联系信息
395    #[serde(skip_serializing_if = "Option::is_none")]
396    pub contact: Option<Contact>,
397    /// 许可信息
398    #[serde(skip_serializing_if = "Option::is_none")]
399    pub license: Option<License>,
400}
401
402impl Default for OpenApiInfo {
403    /// 创建默认的 OpenAPI 信息
404    fn default() -> Self {
405        Self {
406            title: "API".to_string(),
407            version: "1.0.0".to_string(),
408            description: None,
409            terms_of_service: None,
410            contact: None,
411            license: None,
412        }
413    }
414}
415
416/// 联系信息
417#[derive(Debug, Clone, Serialize, Deserialize)]
418pub struct Contact {
419    /// 联系人姓名
420    #[serde(skip_serializing_if = "Option::is_none")]
421    pub name: Option<String>,
422    /// 联系人邮箱
423    #[serde(skip_serializing_if = "Option::is_none")]
424    pub email: Option<String>,
425    /// 联系人 URL
426    #[serde(skip_serializing_if = "Option::is_none")]
427    pub url: Option<String>,
428}
429
430/// 许可信息
431#[derive(Debug, Clone, Serialize, Deserialize)]
432pub struct License {
433    /// 许可证名称
434    pub name: String,
435    /// 许可证 URL
436    #[serde(skip_serializing_if = "Option::is_none")]
437    pub url: Option<String>,
438}
439
440/// 外部文档定义
441#[derive(Debug, Clone, Serialize, Deserialize)]
442pub struct ExternalDocumentation {
443    /// 外部文档 URL
444    pub url: String,
445    /// 外部文档描述
446    #[serde(skip_serializing_if = "Option::is_none")]
447    pub description: Option<String>,
448}
449
450/// 标签定义
451#[derive(Debug, Clone, Serialize, Deserialize)]
452pub struct Tag {
453    /// 标签名称
454    pub name: String,
455    /// 标签描述
456    #[serde(skip_serializing_if = "Option::is_none")]
457    pub description: Option<String>,
458    /// 标签的外部文档
459    #[serde(skip_serializing_if = "Option::is_none")]
460    pub external_docs: Option<ExternalDocumentation>,
461}
462
463/// OpenAPI 文档
464#[derive(Debug, Clone, Serialize, Deserialize)]
465pub struct OpenApiDoc {
466    /// OpenAPI 版本
467    pub openapi: String,
468    /// API 信息
469    pub info: OpenApiInfo,
470    /// 路径定义
471    pub paths: std::collections::BTreeMap<String, PathItem>,
472    /// 组件定义
473    #[serde(skip_serializing_if = "Option::is_none")]
474    pub components: Option<Components>,
475    /// 服务器列表
476    #[serde(skip_serializing_if = "Option::is_none")]
477    pub servers: Option<Vec<Server>>,
478    /// 标签列表
479    #[serde(skip_serializing_if = "Option::is_none")]
480    pub tags: Option<Vec<Tag>>,
481    /// 外部文档
482    #[serde(skip_serializing_if = "Option::is_none")]
483    pub external_docs: Option<ExternalDocumentation>,
484    /// 安全要求
485    #[serde(skip_serializing_if = "Option::is_none")]
486    pub security: Option<Vec<SecurityRequirement>>,
487}
488
489impl Default for OpenApiDoc {
490    /// 创建默认的 OpenAPI 文档
491    fn default() -> Self {
492        Self {
493            openapi: "3.1.0".to_string(),
494            info: OpenApiInfo::default(),
495            paths: std::collections::BTreeMap::new(),
496            components: None,
497            servers: None,
498            tags: None,
499            external_docs: None,
500            security: None,
501        }
502    }
503}
504
505impl OpenApiDoc {
506    /// 创建新的 OpenAPI 文档
507    pub fn new(title: impl Into<String>, version: impl Into<String>) -> Self {
508        Self { info: OpenApiInfo { title: title.into(), version: version.into(), ..Default::default() }, ..Default::default() }
509    }
510
511    /// 设置描述
512    pub fn description(mut self, desc: impl Into<String>) -> Self {
513        self.info.description = Some(desc.into());
514        self
515    }
516
517    /// 添加路径
518    pub fn path(mut self, path: impl Into<String>, item: PathItem) -> Self {
519        self.paths.insert(path.into(), item);
520        self
521    }
522
523    /// 添加 Schema 组件
524    pub fn schema(mut self, name: impl Into<String>, schema: Schema) -> Self {
525        let components = self.components.get_or_insert_with(Components::default);
526        components.schemas.insert(name.into(), schema);
527        self
528    }
529
530    /// 添加安全方案组件
531    pub fn security_scheme(mut self, name: impl Into<String>, scheme: SecurityScheme) -> Self {
532        let components = self.components.get_or_insert_with(Components::default);
533        components.security_schemes.insert(name.into(), scheme);
534        self
535    }
536
537    /// 添加响应组件
538    pub fn response(mut self, name: impl Into<String>, response: Response) -> Self {
539        let components = self.components.get_or_insert_with(Components::default);
540        components.responses.insert(name.into(), response);
541        self
542    }
543
544    /// 添加参数组件
545    pub fn parameter(mut self, name: impl Into<String>, parameter: Parameter) -> Self {
546        let components = self.components.get_or_insert_with(Components::default);
547        components.parameters.insert(name.into(), parameter);
548        self
549    }
550
551    /// 添加请求体组件
552    pub fn request_body(mut self, name: impl Into<String>, body: RequestBody) -> Self {
553        let components = self.components.get_or_insert_with(Components::default);
554        components.request_bodies.insert(name.into(), body);
555        self
556    }
557
558    /// 添加服务器
559    pub fn server(mut self, url: impl Into<String>, description: Option<String>) -> Self {
560        let servers = self.servers.get_or_insert_with(Vec::new);
561        servers.push(Server { url: url.into(), description, variables: None });
562        self
563    }
564
565    /// 添加标签
566    pub fn tag(mut self, name: impl Into<String>, description: Option<String>) -> Self {
567        let tags = self.tags.get_or_insert_with(Vec::new);
568        tags.push(Tag { name: name.into(), description, external_docs: None });
569        self
570    }
571
572    /// 设置外部文档
573    pub fn external_docs(mut self, url: impl Into<String>, description: Option<String>) -> Self {
574        self.external_docs = Some(ExternalDocumentation { url: url.into(), description });
575        self
576    }
577
578    /// 设置安全要求
579    pub fn security(mut self, security: SecurityRequirement) -> Self {
580        let securities = self.security.get_or_insert_with(Vec::new);
581        securities.push(security);
582        self
583    }
584
585    /// 转换为 JSON
586    pub fn to_json(&self) -> serde_json::Value {
587        serde_json::to_value(self).unwrap_or(serde_json::Value::Null)
588    }
589
590    /// 转换为 YAML
591    #[cfg(feature = "yaml")]
592    pub fn to_yaml(&self) -> String {
593        serde_yaml::to_string(self).unwrap_or_default()
594    }
595}
596
597/// 路径项
598#[derive(Debug, Clone, Serialize, Deserialize)]
599pub struct PathItem {
600    /// GET 操作
601    #[serde(skip_serializing_if = "Option::is_none")]
602    pub get: Option<Operation>,
603    /// POST 操作
604    #[serde(skip_serializing_if = "Option::is_none")]
605    pub post: Option<Operation>,
606    /// PUT 操作
607    #[serde(skip_serializing_if = "Option::is_none")]
608    pub put: Option<Operation>,
609    /// DELETE 操作
610    #[serde(skip_serializing_if = "Option::is_none")]
611    pub delete: Option<Operation>,
612    /// PATCH 操作
613    #[serde(skip_serializing_if = "Option::is_none")]
614    pub patch: Option<Operation>,
615    /// HEAD 操作
616    #[serde(skip_serializing_if = "Option::is_none")]
617    pub head: Option<Operation>,
618    /// OPTIONS 操作
619    #[serde(skip_serializing_if = "Option::is_none")]
620    pub options: Option<Operation>,
621    /// TRACE 操作
622    #[serde(skip_serializing_if = "Option::is_none")]
623    pub trace: Option<Operation>,
624    /// 路径描述
625    #[serde(skip_serializing_if = "Option::is_none")]
626    pub description: Option<String>,
627    /// 路径摘要
628    #[serde(skip_serializing_if = "Option::is_none")]
629    pub summary: Option<String>,
630    /// 路径参数
631    #[serde(skip_serializing_if = "Option::is_none")]
632    pub parameters: Option<Vec<ParameterOrReference>>,
633    /// 服务器列表
634    #[serde(skip_serializing_if = "Option::is_none")]
635    pub servers: Option<Vec<Server>>,
636}
637
638impl Default for PathItem {
639    /// 创建默认的路径项
640    fn default() -> Self {
641        Self {
642            get: None,
643            post: None,
644            put: None,
645            delete: None,
646            patch: None,
647            head: None,
648            options: None,
649            trace: None,
650            description: None,
651            summary: None,
652            parameters: None,
653            servers: None,
654        }
655    }
656}
657
658impl PathItem {
659    /// 创建新的路径项
660    pub fn new() -> Self {
661        Self::default()
662    }
663
664    /// 设置 GET 操作
665    pub fn get(mut self, op: Operation) -> Self {
666        self.get = Some(op);
667        self
668    }
669
670    /// 设置 POST 操作
671    pub fn post(mut self, op: Operation) -> Self {
672        self.post = Some(op);
673        self
674    }
675
676    /// 设置 PUT 操作
677    pub fn put(mut self, op: Operation) -> Self {
678        self.put = Some(op);
679        self
680    }
681
682    /// 设置 DELETE 操作
683    pub fn delete(mut self, op: Operation) -> Self {
684        self.delete = Some(op);
685        self
686    }
687
688    /// 设置 PATCH 操作
689    pub fn patch(mut self, op: Operation) -> Self {
690        self.patch = Some(op);
691        self
692    }
693
694    /// 设置 HEAD 操作
695    pub fn head(mut self, op: Operation) -> Self {
696        self.head = Some(op);
697        self
698    }
699
700    /// 设置 OPTIONS 操作
701    pub fn options(mut self, op: Operation) -> Self {
702        self.options = Some(op);
703        self
704    }
705
706    /// 设置 TRACE 操作
707    pub fn trace(mut self, op: Operation) -> Self {
708        self.trace = Some(op);
709        self
710    }
711}
712
713/// 操作定义
714#[derive(Debug, Clone, Serialize, Deserialize)]
715pub struct Operation {
716    /// 操作标签
717    #[serde(skip_serializing_if = "Option::is_none")]
718    pub tags: Option<Vec<String>>,
719    /// 操作摘要
720    #[serde(skip_serializing_if = "Option::is_none")]
721    pub summary: Option<String>,
722    /// 操作描述
723    #[serde(skip_serializing_if = "Option::is_none")]
724    pub description: Option<String>,
725    /// 操作 ID
726    #[serde(skip_serializing_if = "Option::is_none")]
727    pub operation_id: Option<String>,
728    /// 参数列表
729    #[serde(skip_serializing_if = "Option::is_none")]
730    pub parameters: Option<Vec<ParameterOrReference>>,
731    /// 请求体
732    #[serde(skip_serializing_if = "Option::is_none")]
733    pub request_body: Option<RequestBodyOrReference>,
734    /// 响应定义
735    pub responses: std::collections::BTreeMap<String, ResponseOrReference>,
736    /// 回调定义
737    #[serde(skip_serializing_if = "Option::is_none")]
738    pub callbacks: Option<std::collections::BTreeMap<String, Callback>>,
739    /// 弃用标记
740    #[serde(default)]
741    pub deprecated: bool,
742    /// 安全要求
743    #[serde(skip_serializing_if = "Option::is_none")]
744    pub security: Option<Vec<SecurityRequirement>>,
745    /// 服务器列表
746    #[serde(skip_serializing_if = "Option::is_none")]
747    pub servers: Option<Vec<Server>>,
748    /// 外部文档
749    #[serde(skip_serializing_if = "Option::is_none")]
750    pub external_docs: Option<ExternalDocumentation>,
751}
752
753impl Operation {
754    /// 创建新操作
755    pub fn new() -> Self {
756        Self {
757            tags: None,
758            summary: None,
759            description: None,
760            operation_id: None,
761            parameters: None,
762            request_body: None,
763            responses: std::collections::BTreeMap::new(),
764            callbacks: None,
765            deprecated: false,
766            security: None,
767            servers: None,
768            external_docs: None,
769        }
770    }
771
772    /// 设置摘要
773    pub fn summary(mut self, summary: impl Into<String>) -> Self {
774        self.summary = Some(summary.into());
775        self
776    }
777
778    /// 设置描述
779    pub fn description(mut self, desc: impl Into<String>) -> Self {
780        self.description = Some(desc.into());
781        self
782    }
783
784    /// 设置操作 ID
785    pub fn operation_id(mut self, id: impl Into<String>) -> Self {
786        self.operation_id = Some(id.into());
787        self
788    }
789
790    /// 添加标签
791    pub fn tag(mut self, tag: impl Into<String>) -> Self {
792        let tags = self.tags.get_or_insert_with(Vec::new);
793        tags.push(tag.into());
794        self
795    }
796
797    /// 添加参数
798    pub fn parameter(mut self, param: ParameterOrReference) -> Self {
799        let params = self.parameters.get_or_insert_with(Vec::new);
800        params.push(param);
801        self
802    }
803
804    /// 设置请求体
805    pub fn request_body(mut self, body: RequestBodyOrReference) -> Self {
806        self.request_body = Some(body);
807        self
808    }
809
810    /// 添加响应
811    pub fn response(mut self, status: impl Into<String>, resp: ResponseOrReference) -> Self {
812        self.responses.insert(status.into(), resp);
813        self
814    }
815
816    /// 设置弃用
817    pub fn deprecated(mut self, deprecated: bool) -> Self {
818        self.deprecated = deprecated;
819        self
820    }
821}
822
823impl Default for Operation {
824    /// 创建默认的操作
825    fn default() -> Self {
826        Self::new()
827    }
828}
829
830/// 参数定义
831#[derive(Debug, Clone, Serialize, Deserialize)]
832pub struct Parameter {
833    /// 参数名称
834    pub name: String,
835    /// 参数位置
836    #[serde(rename = "in")]
837    pub location: ParameterLocation,
838    /// 参数描述
839    #[serde(skip_serializing_if = "Option::is_none")]
840    pub description: Option<String>,
841    /// 是否必需
842    #[serde(default)]
843    pub required: bool,
844    /// 参数 Schema
845    #[serde(skip_serializing_if = "Option::is_none")]
846    pub schema: Option<Schema>,
847    /// 是否废弃
848    #[serde(default)]
849    pub deprecated: bool,
850    /// 是否允许空值
851    #[serde(default)]
852    pub allow_empty_value: bool,
853    /// 示例值
854    #[serde(skip_serializing_if = "Option::is_none")]
855    pub example: Option<serde_json::Value>,
856    /// 多个示例
857    #[serde(skip_serializing_if = "Option::is_none")]
858    pub examples: Option<std::collections::BTreeMap<String, ExampleOrReference>>,
859}
860
861/// 参数位置
862#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
863#[serde(rename_all = "lowercase")]
864pub enum ParameterLocation {
865    /// 路径参数
866    Path,
867    /// 查询参数
868    Query,
869    /// 请求头参数
870    Header,
871    /// Cookie 参数
872    Cookie,
873}
874
875impl Parameter {
876    /// 创建路径参数
877    pub fn path(name: impl Into<String>) -> Self {
878        Self {
879            name: name.into(),
880            location: ParameterLocation::Path,
881            description: None,
882            required: true,
883            schema: None,
884            deprecated: false,
885            allow_empty_value: false,
886            example: None,
887            examples: None,
888        }
889    }
890
891    /// 创建查询参数
892    pub fn query(name: impl Into<String>) -> Self {
893        Self {
894            name: name.into(),
895            location: ParameterLocation::Query,
896            description: None,
897            required: false,
898            schema: None,
899            deprecated: false,
900            allow_empty_value: false,
901            example: None,
902            examples: None,
903        }
904    }
905
906    /// 创建请求头参数
907    pub fn header(name: impl Into<String>) -> Self {
908        Self {
909            name: name.into(),
910            location: ParameterLocation::Header,
911            description: None,
912            required: false,
913            schema: None,
914            deprecated: false,
915            allow_empty_value: false,
916            example: None,
917            examples: None,
918        }
919    }
920
921    /// 创建 Cookie 参数
922    pub fn cookie(name: impl Into<String>) -> Self {
923        Self {
924            name: name.into(),
925            location: ParameterLocation::Cookie,
926            description: None,
927            required: false,
928            schema: None,
929            deprecated: false,
930            allow_empty_value: false,
931            example: None,
932            examples: None,
933        }
934    }
935
936    /// 设置描述
937    pub fn description(mut self, desc: impl Into<String>) -> Self {
938        self.description = Some(desc.into());
939        self
940    }
941
942    /// 设置必需
943    pub fn required(mut self, required: bool) -> Self {
944        self.required = required;
945        self
946    }
947
948    /// 设置 Schema
949    pub fn schema(mut self, schema: Schema) -> Self {
950        self.schema = Some(schema);
951        self
952    }
953
954    /// 设置废弃
955    pub fn deprecated(mut self, deprecated: bool) -> Self {
956        self.deprecated = deprecated;
957        self
958    }
959
960    /// 设置允许空值
961    pub fn allow_empty_value(mut self, allow: bool) -> Self {
962        self.allow_empty_value = allow;
963        self
964    }
965
966    /// 设置示例值
967    pub fn example(mut self, example: serde_json::Value) -> Self {
968        self.example = Some(example);
969        self
970    }
971}
972
973/// 引用对象
974#[derive(Debug, Clone, Serialize, Deserialize)]
975pub struct Reference {
976    /// 引用地址
977    #[serde(rename = "$ref")]
978    pub ref_path: String,
979}
980
981/// 参数或引用
982#[derive(Debug, Clone, Serialize, Deserialize)]
983#[serde(untagged)]
984pub enum ParameterOrReference {
985    /// 参数对象
986    Parameter(Parameter),
987    /// 引用对象
988    Reference(Reference),
989}
990
991/// 请求体定义
992#[derive(Debug, Clone, Serialize, Deserialize)]
993pub struct RequestBody {
994    /// 请求体描述
995    #[serde(skip_serializing_if = "Option::is_none")]
996    pub description: Option<String>,
997    /// 内容定义
998    pub content: std::collections::BTreeMap<String, MediaType>,
999    /// 是否必需
1000    #[serde(default)]
1001    pub required: bool,
1002}
1003
1004impl RequestBody {
1005    /// 创建 JSON 请求体
1006    pub fn json(schema: Schema) -> Self {
1007        let mut content = std::collections::BTreeMap::new();
1008        content.insert(
1009            "application/json".to_string(),
1010            MediaType { schema: Some(schema), example: None, examples: None, encoding: None },
1011        );
1012        Self { description: None, content, required: true }
1013    }
1014
1015    /// 设置描述
1016    pub fn description(mut self, desc: impl Into<String>) -> Self {
1017        self.description = Some(desc.into());
1018        self
1019    }
1020
1021    /// 设置是否必需
1022    pub fn required(mut self, required: bool) -> Self {
1023        self.required = required;
1024        self
1025    }
1026}
1027
1028/// 请求体或引用
1029#[derive(Debug, Clone, Serialize, Deserialize)]
1030#[serde(untagged)]
1031pub enum RequestBodyOrReference {
1032    /// 请求体对象
1033    RequestBody(RequestBody),
1034    /// 引用对象
1035    Reference(Reference),
1036}
1037
1038/// 媒体类型定义
1039#[derive(Debug, Clone, Serialize, Deserialize)]
1040pub struct MediaType {
1041    /// Schema
1042    #[serde(skip_serializing_if = "Option::is_none")]
1043    pub schema: Option<Schema>,
1044    /// 示例
1045    #[serde(skip_serializing_if = "Option::is_none")]
1046    pub example: Option<serde_json::Value>,
1047    /// 多个示例
1048    #[serde(skip_serializing_if = "Option::is_none")]
1049    pub examples: Option<std::collections::BTreeMap<String, ExampleOrReference>>,
1050    /// 编码定义
1051    #[serde(skip_serializing_if = "Option::is_none")]
1052    pub encoding: Option<std::collections::BTreeMap<String, Encoding>>,
1053}
1054
1055/// 编码定义
1056#[derive(Debug, Clone, Serialize, Deserialize)]
1057pub struct Encoding {
1058    /// 内容类型
1059    #[serde(skip_serializing_if = "Option::is_none")]
1060    pub content_type: Option<String>,
1061    /// 请求头
1062    #[serde(skip_serializing_if = "Option::is_none")]
1063    pub headers: Option<std::collections::BTreeMap<String, HeaderOrReference>>,
1064    /// 样式
1065    #[serde(skip_serializing_if = "Option::is_none")]
1066    pub style: Option<String>,
1067    /// 是否展开
1068    #[serde(default)]
1069    pub explode: bool,
1070    /// 是否允许保留字符
1071    #[serde(default)]
1072    pub allow_reserved: bool,
1073}
1074
1075/// 响应定义
1076#[derive(Debug, Clone, Serialize, Deserialize)]
1077pub struct Response {
1078    /// 响应描述
1079    pub description: String,
1080    /// 内容定义
1081    #[serde(skip_serializing_if = "Option::is_none")]
1082    pub content: Option<std::collections::BTreeMap<String, MediaType>>,
1083    /// 响应头
1084    #[serde(skip_serializing_if = "Option::is_none")]
1085    pub headers: Option<std::collections::BTreeMap<String, HeaderOrReference>>,
1086    /// 链接
1087    #[serde(skip_serializing_if = "Option::is_none")]
1088    pub links: Option<std::collections::BTreeMap<String, LinkOrReference>>,
1089}
1090
1091impl Response {
1092    /// 创建新响应
1093    pub fn new(description: impl Into<String>) -> Self {
1094        Self { description: description.into(), content: None, headers: None, links: None }
1095    }
1096
1097    /// 添加 JSON 响应
1098    pub fn json(mut self, schema: Schema) -> Self {
1099        let content = self.content.get_or_insert_with(std::collections::BTreeMap::new);
1100        content.insert(
1101            "application/json".to_string(),
1102            MediaType { schema: Some(schema), example: None, examples: None, encoding: None },
1103        );
1104        self
1105    }
1106}
1107
1108/// 响应或引用
1109#[derive(Debug, Clone, Serialize, Deserialize)]
1110#[serde(untagged)]
1111pub enum ResponseOrReference {
1112    /// 响应对象
1113    Response(Response),
1114    /// 引用对象
1115    Reference(Reference),
1116}
1117
1118/// 头部定义
1119#[derive(Debug, Clone, Serialize, Deserialize)]
1120pub struct Header {
1121    /// 头部描述
1122    #[serde(skip_serializing_if = "Option::is_none")]
1123    pub description: Option<String>,
1124    /// 是否必需
1125    #[serde(default)]
1126    pub required: bool,
1127    /// Schema
1128    #[serde(skip_serializing_if = "Option::is_none")]
1129    pub schema: Option<Schema>,
1130    /// 是否废弃
1131    #[serde(default)]
1132    pub deprecated: bool,
1133    /// 示例值
1134    #[serde(skip_serializing_if = "Option::is_none")]
1135    pub example: Option<serde_json::Value>,
1136    /// 多个示例
1137    #[serde(skip_serializing_if = "Option::is_none")]
1138    pub examples: Option<std::collections::BTreeMap<String, ExampleOrReference>>,
1139}
1140
1141/// 头部或引用
1142#[derive(Debug, Clone, Serialize, Deserialize)]
1143#[serde(untagged)]
1144pub enum HeaderOrReference {
1145    /// 头部对象
1146    Header(Header),
1147    /// 引用对象
1148    Reference(Reference),
1149}
1150
1151/// 示例定义
1152#[derive(Debug, Clone, Serialize, Deserialize)]
1153pub struct Example {
1154    /// 示例摘要
1155    #[serde(skip_serializing_if = "Option::is_none")]
1156    pub summary: Option<String>,
1157    /// 示例描述
1158    #[serde(skip_serializing_if = "Option::is_none")]
1159    pub description: Option<String>,
1160    /// 示例值
1161    #[serde(skip_serializing_if = "Option::is_none")]
1162    pub value: Option<serde_json::Value>,
1163    /// 外部示例值 URL
1164    #[serde(skip_serializing_if = "Option::is_none")]
1165    pub external_value: Option<String>,
1166}
1167
1168/// 示例或引用
1169#[derive(Debug, Clone, Serialize, Deserialize)]
1170#[serde(untagged)]
1171pub enum ExampleOrReference {
1172    /// 示例对象
1173    Example(Example),
1174    /// 引用对象
1175    Reference(Reference),
1176}
1177
1178/// 链接定义
1179#[derive(Debug, Clone, Serialize, Deserialize)]
1180pub struct Link {
1181    /// 链接操作引用
1182    #[serde(skip_serializing_if = "Option::is_none")]
1183    pub operation_ref: Option<String>,
1184    /// 链接操作 ID
1185    #[serde(skip_serializing_if = "Option::is_none")]
1186    pub operation_id: Option<String>,
1187    /// 链接参数
1188    #[serde(skip_serializing_if = "Option::is_none")]
1189    pub parameters: Option<std::collections::BTreeMap<String, serde_json::Value>>,
1190    /// 链接请求体
1191    #[serde(skip_serializing_if = "Option::is_none")]
1192    pub request_body: Option<serde_json::Value>,
1193    /// 链接描述
1194    #[serde(skip_serializing_if = "Option::is_none")]
1195    pub description: Option<String>,
1196    /// 链接服务器
1197    #[serde(skip_serializing_if = "Option::is_none")]
1198    pub server: Option<Server>,
1199}
1200
1201/// 链接或引用
1202#[derive(Debug, Clone, Serialize, Deserialize)]
1203#[serde(untagged)]
1204pub enum LinkOrReference {
1205    /// 链接对象
1206    Link(Link),
1207    /// 引用对象
1208    Reference(Reference),
1209}
1210
1211/// 回调定义
1212#[derive(Debug, Clone, Serialize, Deserialize)]
1213pub struct Callback {
1214    /// 回调路径项
1215    #[serde(flatten)]
1216    pub paths: std::collections::BTreeMap<String, PathItem>,
1217}
1218
1219/// 安全要求
1220#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1221pub struct SecurityRequirement {
1222    /// 安全方案名称和范围
1223    #[serde(flatten)]
1224    pub schemes: std::collections::BTreeMap<String, Vec<String>>,
1225}
1226
1227impl SecurityRequirement {
1228    /// 创建新的安全要求
1229    pub fn new() -> Self {
1230        Self::default()
1231    }
1232
1233    /// 添加安全方案
1234    pub fn scheme(mut self, name: impl Into<String>, scopes: Vec<&str>) -> Self {
1235        self.schemes.insert(name.into(), scopes.into_iter().map(String::from).collect());
1236        self
1237    }
1238}
1239
1240/// 安全方案类型
1241#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1242#[serde(rename_all = "lowercase")]
1243pub enum SecuritySchemeType {
1244    /// API Key
1245    ApiKey,
1246    /// HTTP 认证
1247    Http,
1248    /// OAuth2
1249    OAuth2,
1250    /// OpenID Connect
1251    OpenIdConnect,
1252}
1253
1254/// API Key 位置
1255#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1256#[serde(rename_all = "lowercase")]
1257pub enum ApiKeyLocation {
1258    /// 查询参数
1259    Query,
1260    /// 请求头
1261    Header,
1262    /// Cookie
1263    Cookie,
1264}
1265
1266/// 安全方案
1267#[derive(Debug, Clone, Serialize, Deserialize)]
1268pub struct SecurityScheme {
1269    /// 安全方案类型
1270    #[serde(rename = "type")]
1271    pub scheme_type: SecuritySchemeType,
1272    /// 安全方案描述
1273    #[serde(skip_serializing_if = "Option::is_none")]
1274    pub description: Option<String>,
1275    /// API Key 名称(仅 apiKey 类型)
1276    #[serde(skip_serializing_if = "Option::is_none")]
1277    pub name: Option<String>,
1278    /// API Key 位置(仅 apiKey 类型)
1279    #[serde(rename = "in")]
1280    #[serde(skip_serializing_if = "Option::is_none")]
1281    pub location: Option<ApiKeyLocation>,
1282    /// HTTP 方案名称(仅 http 类型)
1283    #[serde(skip_serializing_if = "Option::is_none")]
1284    pub scheme: Option<String>,
1285    /// HTTP Bearer 格式(仅 http 类型)
1286    #[serde(skip_serializing_if = "Option::is_none")]
1287    pub bearer_format: Option<String>,
1288    /// OAuth2 流程(仅 oauth2 类型)
1289    #[serde(skip_serializing_if = "Option::is_none")]
1290    pub flows: Option<OAuthFlows>,
1291    /// OpenID Connect URL(仅 openIdConnect 类型)
1292    #[serde(skip_serializing_if = "Option::is_none")]
1293    pub open_id_connect_url: Option<String>,
1294}
1295
1296impl SecurityScheme {
1297    /// 创建 API Key 安全方案
1298    pub fn api_key(name: impl Into<String>, location: ApiKeyLocation) -> Self {
1299        Self {
1300            scheme_type: SecuritySchemeType::ApiKey,
1301            description: None,
1302            name: Some(name.into()),
1303            location: Some(location),
1304            scheme: None,
1305            bearer_format: None,
1306            flows: None,
1307            open_id_connect_url: None,
1308        }
1309    }
1310
1311    /// 创建 HTTP Basic 安全方案
1312    pub fn basic() -> Self {
1313        Self {
1314            scheme_type: SecuritySchemeType::Http,
1315            description: None,
1316            name: None,
1317            location: None,
1318            scheme: Some("basic".to_string()),
1319            bearer_format: None,
1320            flows: None,
1321            open_id_connect_url: None,
1322        }
1323    }
1324
1325    /// 创建 HTTP Bearer 安全方案
1326    pub fn bearer(format: Option<String>) -> Self {
1327        Self {
1328            scheme_type: SecuritySchemeType::Http,
1329            description: None,
1330            name: None,
1331            location: None,
1332            scheme: Some("bearer".to_string()),
1333            bearer_format: format,
1334            flows: None,
1335            open_id_connect_url: None,
1336        }
1337    }
1338
1339    /// 创建 OAuth2 安全方案
1340    pub fn oauth2(flows: OAuthFlows) -> Self {
1341        Self {
1342            scheme_type: SecuritySchemeType::OAuth2,
1343            description: None,
1344            name: None,
1345            location: None,
1346            scheme: None,
1347            bearer_format: None,
1348            flows: Some(flows),
1349            open_id_connect_url: None,
1350        }
1351    }
1352
1353    /// 创建 OpenID Connect 安全方案
1354    pub fn open_id_connect(url: impl Into<String>) -> Self {
1355        Self {
1356            scheme_type: SecuritySchemeType::OpenIdConnect,
1357            description: None,
1358            name: None,
1359            location: None,
1360            scheme: None,
1361            bearer_format: None,
1362            flows: None,
1363            open_id_connect_url: Some(url.into()),
1364        }
1365    }
1366
1367    /// 设置描述
1368    pub fn description(mut self, desc: impl Into<String>) -> Self {
1369        self.description = Some(desc.into());
1370        self
1371    }
1372}
1373
1374/// OAuth2 流程
1375#[derive(Debug, Clone, Serialize, Deserialize)]
1376pub struct OAuthFlows {
1377    /// Implicit 流程
1378    #[serde(skip_serializing_if = "Option::is_none")]
1379    pub implicit: Option<OAuthFlow>,
1380    /// Password 流程
1381    #[serde(skip_serializing_if = "Option::is_none")]
1382    pub password: Option<OAuthFlow>,
1383    /// Client Credentials 流程
1384    #[serde(skip_serializing_if = "Option::is_none")]
1385    pub client_credentials: Option<OAuthFlow>,
1386    /// Authorization Code 流程
1387    #[serde(skip_serializing_if = "Option::is_none")]
1388    pub authorization_code: Option<OAuthFlow>,
1389}
1390
1391/// OAuth2 流程
1392#[derive(Debug, Clone, Serialize, Deserialize)]
1393pub struct OAuthFlow {
1394    /// 授权 URL
1395    #[serde(skip_serializing_if = "Option::is_none")]
1396    pub authorization_url: Option<String>,
1397    /// Token URL
1398    #[serde(skip_serializing_if = "Option::is_none")]
1399    pub token_url: Option<String>,
1400    /// 刷新 URL
1401    #[serde(skip_serializing_if = "Option::is_none")]
1402    pub refresh_url: Option<String>,
1403    /// 可用的范围
1404    pub scopes: std::collections::BTreeMap<String, String>,
1405}
1406
1407impl OAuthFlow {
1408    /// 创建新的 OAuth 流程
1409    pub fn new() -> Self {
1410        Self { authorization_url: None, token_url: None, refresh_url: None, scopes: std::collections::BTreeMap::new() }
1411    }
1412
1413    /// 设置授权 URL
1414    pub fn authorization_url(mut self, url: impl Into<String>) -> Self {
1415        self.authorization_url = Some(url.into());
1416        self
1417    }
1418
1419    /// 设置 Token URL
1420    pub fn token_url(mut self, url: impl Into<String>) -> Self {
1421        self.token_url = Some(url.into());
1422        self
1423    }
1424
1425    /// 设置刷新 URL
1426    pub fn refresh_url(mut self, url: impl Into<String>) -> Self {
1427        self.refresh_url = Some(url.into());
1428        self
1429    }
1430
1431    /// 添加范围
1432    pub fn scope(mut self, name: impl Into<String>, description: impl Into<String>) -> Self {
1433        self.scopes.insert(name.into(), description.into());
1434        self
1435    }
1436}
1437
1438impl Default for OAuthFlow {
1439    fn default() -> Self {
1440        Self::new()
1441    }
1442}
1443
1444/// 组件定义
1445#[derive(Debug, Clone, Serialize, Deserialize, Default)]
1446pub struct Components {
1447    /// Schema 定义
1448    #[serde(skip_serializing_if = "std::collections::BTreeMap::is_empty")]
1449    pub schemas: std::collections::BTreeMap<String, Schema>,
1450    /// 响应定义
1451    #[serde(skip_serializing_if = "std::collections::BTreeMap::is_empty")]
1452    pub responses: std::collections::BTreeMap<String, Response>,
1453    /// 参数定义
1454    #[serde(skip_serializing_if = "std::collections::BTreeMap::is_empty")]
1455    pub parameters: std::collections::BTreeMap<String, Parameter>,
1456    /// 示例定义
1457    #[serde(skip_serializing_if = "std::collections::BTreeMap::is_empty")]
1458    pub examples: std::collections::BTreeMap<String, Example>,
1459    /// 请求体定义
1460    #[serde(skip_serializing_if = "std::collections::BTreeMap::is_empty")]
1461    pub request_bodies: std::collections::BTreeMap<String, RequestBody>,
1462    /// 头部定义
1463    #[serde(skip_serializing_if = "std::collections::BTreeMap::is_empty")]
1464    pub headers: std::collections::BTreeMap<String, Header>,
1465    /// 安全方案定义
1466    #[serde(skip_serializing_if = "std::collections::BTreeMap::is_empty")]
1467    pub security_schemes: std::collections::BTreeMap<String, SecurityScheme>,
1468    /// 链接定义
1469    #[serde(skip_serializing_if = "std::collections::BTreeMap::is_empty")]
1470    pub links: std::collections::BTreeMap<String, Link>,
1471    /// 回调定义
1472    #[serde(skip_serializing_if = "std::collections::BTreeMap::is_empty")]
1473    pub callbacks: std::collections::BTreeMap<String, Callback>,
1474}
1475
1476/// 服务器定义
1477#[derive(Debug, Clone, Serialize, Deserialize)]
1478pub struct Server {
1479    /// 服务器 URL
1480    pub url: String,
1481    /// 服务器描述
1482    #[serde(skip_serializing_if = "Option::is_none")]
1483    pub description: Option<String>,
1484    /// 服务器变量
1485    #[serde(skip_serializing_if = "Option::is_none")]
1486    pub variables: Option<std::collections::BTreeMap<String, ServerVariable>>,
1487}
1488
1489/// 服务器变量
1490#[derive(Debug, Clone, Serialize, Deserialize)]
1491pub struct ServerVariable {
1492    /// 默认值
1493    pub default: String,
1494    /// 枚举值
1495    #[serde(skip_serializing_if = "Option::is_none")]
1496    pub enum_values: Option<Vec<String>>,
1497    /// 描述
1498    #[serde(skip_serializing_if = "Option::is_none")]
1499    pub description: Option<String>,
1500}
1501
1502impl ToSchema for String {
1503    fn schema() -> Schema {
1504        Schema::string()
1505    }
1506}
1507
1508impl ToSchema for i64 {
1509    fn schema() -> Schema {
1510        Schema::integer()
1511    }
1512}
1513
1514impl ToSchema for i32 {
1515    fn schema() -> Schema {
1516        Schema::integer()
1517    }
1518}
1519
1520impl ToSchema for i16 {
1521    fn schema() -> Schema {
1522        Schema::integer()
1523    }
1524}
1525
1526impl ToSchema for i8 {
1527    fn schema() -> Schema {
1528        Schema::integer()
1529    }
1530}
1531
1532impl ToSchema for u64 {
1533    fn schema() -> Schema {
1534        Schema::integer()
1535    }
1536}
1537
1538impl ToSchema for u32 {
1539    fn schema() -> Schema {
1540        Schema::integer()
1541    }
1542}
1543
1544impl ToSchema for u16 {
1545    fn schema() -> Schema {
1546        Schema::integer()
1547    }
1548}
1549
1550impl ToSchema for u8 {
1551    fn schema() -> Schema {
1552        Schema::integer()
1553    }
1554}
1555
1556impl ToSchema for f64 {
1557    fn schema() -> Schema {
1558        Schema::number()
1559    }
1560}
1561
1562impl ToSchema for f32 {
1563    fn schema() -> Schema {
1564        Schema::number()
1565    }
1566}
1567
1568impl ToSchema for bool {
1569    fn schema() -> Schema {
1570        Schema::boolean()
1571    }
1572}
1573
1574impl<T: ToSchema> ToSchema for Vec<T> {
1575    fn schema() -> Schema {
1576        Schema::array(T::schema())
1577    }
1578}
1579
1580impl<T: ToSchema> ToSchema for Option<T> {
1581    fn schema() -> Schema {
1582        T::schema().nullable(true)
1583    }
1584}
1585
1586impl ToSchema for serde_json::Value {
1587    fn schema() -> Schema {
1588        <Schema as Default>::default()
1589    }
1590}