go_away/
metadata.rs

1use crate::types::{FieldType, Primitive};
2
3use super::TypeRegistry;
4
5/// Exposes metadata about a type that can be used to generate other
6/// versions of that type in other languages.
7///
8/// This is usually intended to be derived rather than manually implemented.
9pub trait TypeMetadata {
10    /// Populates `TypeRegistry` with this type and any of it's
11    /// contained types and returns a `FieldType`
12    fn metadata(registry: &mut TypeRegistry) -> FieldType;
13}
14
15impl<T> TypeMetadata for Vec<T>
16where
17    T: TypeMetadata,
18{
19    fn metadata(registry: &mut TypeRegistry) -> FieldType {
20        FieldType::List(Box::new(T::metadata(registry)))
21    }
22}
23
24impl<T> TypeMetadata for Option<T>
25where
26    T: TypeMetadata,
27{
28    fn metadata(registry: &mut TypeRegistry) -> FieldType {
29        FieldType::Optional(Box::new(T::metadata(registry)))
30    }
31}
32
33impl<K, V> TypeMetadata for std::collections::HashMap<K, V>
34where
35    K: TypeMetadata,
36    V: TypeMetadata,
37{
38    fn metadata(registry: &mut TypeRegistry) -> FieldType {
39        let key = Box::new(K::metadata(registry));
40        let value = Box::new(V::metadata(registry));
41
42        FieldType::Map { key, value }
43    }
44}
45
46impl TypeMetadata for String {
47    fn metadata(_: &mut TypeRegistry) -> FieldType {
48        FieldType::Primitive(Primitive::String)
49    }
50}
51
52impl TypeMetadata for str {
53    fn metadata(_: &mut TypeRegistry) -> FieldType {
54        FieldType::Primitive(Primitive::String)
55    }
56}
57
58impl TypeMetadata for bool {
59    fn metadata(_: &mut TypeRegistry) -> FieldType {
60        FieldType::Primitive(Primitive::Bool)
61    }
62}
63
64#[cfg(feature = "uuid")]
65impl TypeMetadata for uuid::Uuid {
66    fn metadata(_: &mut TypeRegistry) -> FieldType {
67        FieldType::Primitive(Primitive::String)
68    }
69}
70
71#[cfg(feature = "chrono")]
72impl<Tz: chrono::offset::TimeZone> TypeMetadata for chrono::DateTime<Tz> {
73    fn metadata(_: &mut TypeRegistry) -> FieldType {
74        FieldType::Primitive(Primitive::Time)
75    }
76}
77
78macro_rules! metadata_for_int {
79    () => {};
80    ($this:ty, $($tail:tt)*) => {
81        metadata_for_int!($this);
82        metadata_for_int!{$($tail)*}
83    };
84    ($int:ty) => {
85        impl TypeMetadata for $int {
86            fn metadata(_: &mut TypeRegistry) -> FieldType {
87                FieldType::Primitive(Primitive::Int)
88            }
89        }
90    };
91}
92
93metadata_for_int! {i8, i16, i32, i64, i128, u8, u16, u32, u64, u128}
94
95macro_rules! metadata_for_float {
96    () => {};
97    ($this:ty, $($tail:tt)*) => {
98        metadata_for_float!($this);
99        metadata_for_float!{$($tail)*}
100    };
101    ($fl:ty) => {
102        impl TypeMetadata for $fl {
103            fn metadata(_: &mut TypeRegistry) -> FieldType {
104                FieldType::Primitive(Primitive::Float)
105            }
106        }
107    };
108}
109
110metadata_for_float! {f32, f64}