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}