predawn_schema/impls/
string.rs

1use std::{
2    borrow::Cow,
3    collections::BTreeMap,
4    net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6},
5    path::{Path, PathBuf},
6};
7
8use openapiv3::{Schema, SchemaData, SchemaKind, StringType, Type, VariantOrUnknownOrEmpty};
9
10use crate::ToSchema;
11
12macro_rules! string_impl {
13    ($ty:ty) => {
14        string_impl!($ty, VariantOrUnknownOrEmpty::Empty);
15    };
16    ($ty:ty, $format:literal) => {
17        string_impl!($ty, VariantOrUnknownOrEmpty::Unknown($format.to_string()));
18    };
19    ($ty:ty, $format:expr) => {
20        impl ToSchema for $ty {
21            fn title() -> Cow<'static, str> {
22                stringify!($ty).into()
23            }
24
25            fn schema(_: &mut BTreeMap<String, Schema>, _: &mut Vec<String>) -> Schema {
26                let ty = StringType {
27                    format: $format,
28                    ..Default::default()
29                };
30
31                Schema {
32                    schema_data: SchemaData {
33                        title: Some(Self::title().into()),
34                        ..Default::default()
35                    },
36                    schema_kind: SchemaKind::Type(Type::String(ty)),
37                }
38            }
39        }
40    };
41}
42
43string_impl!(str);
44string_impl!(String);
45string_impl!(Path);
46string_impl!(PathBuf);
47string_impl!(Ipv4Addr, "ipv4");
48string_impl!(Ipv6Addr, "ipv6");
49string_impl!(SocketAddrV4);
50string_impl!(SocketAddrV6);
51
52macro_rules! one_of_string_impl {
53    ($ty:ty; [$($elem:ty),+ $(,)?]) => {
54        impl ToSchema for $ty {
55            fn title() -> Cow<'static, str> {
56                stringify!($ty).into()
57            }
58
59            fn schema(schemas: &mut BTreeMap<String, Schema>, schemas_in_progress: &mut Vec<String>) -> Schema {
60                Schema {
61                    schema_data: SchemaData {
62                        title: Some(Self::title().into()),
63                        ..Default::default()
64                    },
65                    schema_kind: SchemaKind::OneOf {
66                        one_of: [
67                            $(
68                                <$elem>::schema_ref(schemas, schemas_in_progress),
69                            )+
70                        ]
71                        .to_vec(),
72                    },
73                }
74            }
75        }
76    };
77}
78
79one_of_string_impl!(IpAddr; [Ipv4Addr, Ipv6Addr]);
80one_of_string_impl!(SocketAddr; [SocketAddrV4, SocketAddrV6]);