type_protocol/
derive.rs

1use std::collections::{HashMap, BTreeMap, HashSet, BTreeSet};
2
3use crate::{RustIdent, Typing, UniversalType};
4
5#[doc(hidden)]
6#[macro_export]
7macro_rules! nz {
8    ($i: literal) => {
9        match ::core::num::NonZeroUsize::new($i) {
10            Some(x) => x,
11            None => unreachable!(),
12        }
13    };
14}
15
16macro_rules! impl_common {
17    ($ty: ty, $branch: ident) => {
18        impl ToTypeProtocol for $ty {
19            fn type_protocol() -> Typing<RustIdent> {
20                Typing::Common(UniversalType::$branch)
21            }
22        }
23    };
24    ($ty: ty, $branch: ident, $len: literal) => {
25        impl ToTypeProtocol for $ty {
26            fn type_protocol() -> Typing<RustIdent> {
27                Typing::Common(UniversalType::$branch(nz!($len)))
28            }
29        }
30    };
31}
32
33pub trait ToTypeProtocol {
34    fn type_protocol() -> Typing<RustIdent>;
35}
36
37impl_common!(bool, Bool);
38impl_common!(u8, UInt, 1);
39impl_common!(u16, UInt, 2);
40impl_common!(u32, UInt, 4);
41impl_common!(u64, UInt, 8);
42impl_common!(u128, UInt, 16);
43impl_common!(i8, Int, 1);
44impl_common!(i16, Int, 2);
45impl_common!(i32, Int, 4);
46impl_common!(i64, Int, 8);
47impl_common!(i128, Int, 16);
48impl_common!(f32, Float, 4);
49impl_common!(f64, Float, 8);
50impl_common!(usize, USize);
51impl_common!(isize, ISize);
52impl_common!(char, Char);
53impl_common!(String, String);
54
55impl<T: ToTypeProtocol> ToTypeProtocol for Option<T> {
56    fn type_protocol() -> Typing<RustIdent> {
57        Typing::Option(T::type_protocol().boxed())
58    }
59}
60
61impl<T: ToTypeProtocol, const N: usize> ToTypeProtocol for [T; N] {
62    fn type_protocol() -> Typing<RustIdent> {
63        Typing::Array(N, T::type_protocol().boxed())
64    }
65}
66
67impl<T: ToTypeProtocol> ToTypeProtocol for Vec<T> {
68    fn type_protocol() -> Typing<RustIdent> {
69        Typing::Vec(T::type_protocol().boxed())
70    }
71}
72
73impl<T: ToTypeProtocol> ToTypeProtocol for HashSet<T> {
74    fn type_protocol() -> Typing<RustIdent> {
75        Typing::Set(T::type_protocol().boxed())
76    }
77}
78
79impl<T: ToTypeProtocol> ToTypeProtocol for BTreeSet<T> {
80    fn type_protocol() -> Typing<RustIdent> {
81        Typing::Set(T::type_protocol().boxed())
82    }
83}
84
85impl<A: ToTypeProtocol, B: ToTypeProtocol> ToTypeProtocol for HashMap<A, B> {
86    fn type_protocol() -> Typing<RustIdent> {
87        Typing::Map(A::type_protocol().boxed(), B::type_protocol().boxed())
88    }
89}
90
91impl<A: ToTypeProtocol, B: ToTypeProtocol> ToTypeProtocol for BTreeMap<A, B> {
92    fn type_protocol() -> Typing<RustIdent> {
93        Typing::Map(A::type_protocol().boxed(), B::type_protocol().boxed())
94    }
95}