predawn_schema/impls/
primitive.rs

1use std::{borrow::Cow, collections::BTreeMap};
2
3use openapiv3::{
4    ArrayType, BooleanType, IntegerType, NumberType, Schema, SchemaData, SchemaKind, StringType,
5    Type, VariantOrUnknownOrEmpty,
6};
7use paste::paste;
8
9use crate::ToSchema;
10
11impl ToSchema for bool {
12    fn title() -> Cow<'static, str> {
13        "bool".into()
14    }
15
16    fn schema(_: &mut BTreeMap<String, Schema>, _: &mut Vec<String>) -> Schema {
17        Schema {
18            schema_data: SchemaData {
19                title: Some(Self::title().into()),
20                ..Default::default()
21            },
22            schema_kind: SchemaKind::Type(Type::Boolean(BooleanType::default())),
23        }
24    }
25}
26
27impl ToSchema for char {
28    fn title() -> Cow<'static, str> {
29        "char".into()
30    }
31
32    fn schema(_: &mut BTreeMap<String, Schema>, _: &mut Vec<String>) -> Schema {
33        Schema {
34            schema_data: SchemaData {
35                title: Some(Self::title().into()),
36                ..Default::default()
37            },
38            schema_kind: SchemaKind::Type(Type::String(StringType {
39                min_length: Some(1),
40                max_length: Some(1),
41                ..Default::default()
42            })),
43        }
44    }
45}
46
47macro_rules! simple_impl {
48    ($ty:ty, $ty_variant:ident, $format:literal) => {
49        impl ToSchema for $ty {
50            fn title() -> Cow<'static, str> {
51                stringify!($ty).into()
52            }
53
54            fn schema(_: &mut BTreeMap<String, Schema>, _: &mut Vec<String>) -> Schema {
55                Schema {
56                    schema_data: SchemaData {
57                        title: Some(Self::title().into()),
58                        ..Default::default()
59                    },
60                    schema_kind: paste! {
61                        SchemaKind::Type(Type::$ty_variant([<$ty_variant Type>] {
62                            format: VariantOrUnknownOrEmpty::Unknown($format.to_string()),
63                            ..Default::default()
64                        }))
65                    },
66                }
67            }
68        }
69    };
70}
71
72simple_impl!(f32, Number, "float");
73simple_impl!(f64, Number, "double");
74simple_impl!(i8, Integer, "int8");
75simple_impl!(i16, Integer, "int16");
76simple_impl!(i32, Integer, "int32");
77simple_impl!(i64, Integer, "int64");
78simple_impl!(i128, Integer, "int128");
79simple_impl!(isize, Integer, "int");
80
81macro_rules! unsigned_impl {
82    ($ty:ty, $format:literal) => {
83        impl ToSchema for $ty {
84            fn title() -> Cow<'static, str> {
85                stringify!($ty).into()
86            }
87
88            fn schema(_: &mut BTreeMap<String, Schema>, _: &mut Vec<String>) -> Schema {
89                Schema {
90                    schema_data: SchemaData {
91                        title: Some(Self::title().into()),
92                        ..Default::default()
93                    },
94                    schema_kind: SchemaKind::Type(Type::Integer(IntegerType {
95                        format: VariantOrUnknownOrEmpty::Unknown($format.to_string()),
96                        minimum: Some(0),
97                        ..Default::default()
98                    })),
99                }
100            }
101        }
102    };
103}
104
105unsigned_impl!(u8, "uint8");
106unsigned_impl!(u16, "uint16");
107unsigned_impl!(u32, "uint32");
108unsigned_impl!(u64, "uint64");
109unsigned_impl!(u128, "uint128");
110unsigned_impl!(usize, "uint");
111
112impl<T: ToSchema, const N: usize> ToSchema for [T; N] {
113    fn title() -> Cow<'static, str> {
114        format!("Array{}<{}>", N, T::title()).into()
115    }
116
117    fn schema(
118        schemas: &mut BTreeMap<String, Schema>,
119        schemas_in_progress: &mut Vec<String>,
120    ) -> Schema {
121        let ty = ArrayType {
122            items: Some(T::schema_ref_box(schemas, schemas_in_progress)),
123            min_items: Some(N),
124            max_items: Some(N),
125            unique_items: false,
126        };
127
128        Schema {
129            schema_data: SchemaData {
130                title: Some(Self::title().into()),
131                ..Default::default()
132            },
133            schema_kind: SchemaKind::Type(Type::Array(ty)),
134        }
135    }
136}