1use std::collections::{HashMap, HashSet};
2
3pub use rts_derive::rts_to_string;
4pub use rts_derive::RTS;
5
6pub trait RTS<A1 = (), A2 = (), B = ()> {
7 fn to_type_string(&self) -> String {
8 "any".into()
9 }
10 fn to_type_name(&self) -> String {
11 "any".into()
12 }
13}
14
15macro_rules! impl_rts_number {
16 ( $( $a:ty ) * ) => {
17 $(
18 impl RTS for $a {
19 fn to_type_string(&self)->String{
20 "number".into()
21 }
22 fn to_type_name(&self)->String{
23 "number".into()
24 }
25 }
26
27 )*
28
29 };
30}
31
32macro_rules! impl_rts {
33 ( $( ($a:ty, $b:expr) ) , * ) => {
34 $(
35 impl RTS for $a {
36 fn to_type_string(&self)->String{
37 $b.into()
38 }
39 fn to_type_name(&self)->String{
40 $b.into()
41 }
42 }
43
44 )*
45
46 };
47}
48
49impl<K: RTS + Default, V: RTS + Default> RTS for HashMap<K, V> {
50 fn to_type_string(&self) -> String {
51 format!(
52 "Map<{}, {}>",
53 K::default().to_type_string(),
54 V::default().to_type_string(),
55 )
56 }
57
58 fn to_type_name(&self) -> String {
59 format!(
60 "Map<{}, {}>",
61 K::default().to_type_name(),
62 V::default().to_type_name(),
63 )
64 }
65}
66
67impl<V: RTS + Default> RTS for HashSet<V> {
68 fn to_type_string(&self) -> String {
69 format!("Set<{}>", V::default().to_type_string(),)
70 }
71 fn to_type_name(&self) -> String {
72 format!("Set<{}>", V::default().to_type_name(),)
73 }
74}
75
76impl<V: RTS + Default> RTS for Vec<V> {
77 fn to_type_string(&self) -> String {
78 format!("Array<{}>", V::default().to_type_string(),)
79 }
80 fn to_type_name(&self) -> String {
81 format!("Array<{}>", V::default().to_type_name(),)
82 }
83}
84
85fn get_name(s: &str) -> &str {
86 s.split("::").last().expect("function name error")
87}
88
89impl_rts_number!(i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 );
90
91impl_rts!((bool, "bool"), (char, "string"), (String, "string"));
92
93impl<F, A, R> RTS<(A), (R)> for F
105where
106 F: Fn(A) -> R,
107 A: RTS,
108 R: RTS,
109{
110 fn to_type_string(&self) -> String {
111 let fn_name = heck::AsLowerCamelCase(get_name(std::any::type_name::<F>()));
112 let arg_name = get_name(std::any::type_name::<A>());
113 let rt_name = get_name(std::any::type_name::<R>());
114 format!(
115 "declare function {}(arg0: {}): {};",
116 fn_name, arg_name, rt_name
117 )
118 }
119
120 fn to_type_name(&self) -> String {
121 "any".into()
122 }
123}
124
125impl<F> RTS for F
127where
128 F: Fn(),
129{
130 fn to_type_string(&self) -> String {
131 let fn_name = heck::AsLowerCamelCase(get_name(std::any::type_name::<F>()));
132 format!("declare function {}();", fn_name)
133 }
134
135 fn to_type_name(&self) -> String {
136 "any".into()
137 }
138}
139
140impl<F, R> RTS<R> for F
142where
143 F: Fn() -> R,
144 R: RTS,
145{
146 fn to_type_string(&self) -> String {
147 let fn_name = heck::AsLowerCamelCase(get_name(std::any::type_name::<F>()));
148 let rt_name = get_name(std::any::type_name::<R>());
149 format!("declare function {}(): {};", fn_name, rt_name)
150 }
151
152 fn to_type_name(&self) -> String {
153 "any".into()
154 }
155}
156
157impl<F, A1, A2, R> RTS<A1, A2, R> for F
159where
160 F: Fn(A1, A2) -> R,
161 A1: RTS,
162 A2: RTS,
163 R: RTS,
164{
165 fn to_type_string(&self) -> String {
166 let fn_name = heck::AsLowerCamelCase(get_name(std::any::type_name::<F>()));
167 let rt_name = get_name(std::any::type_name::<R>());
168 let arg1_name = get_name(std::any::type_name::<A1>());
169 let arg2_name = get_name(std::any::type_name::<A2>());
170 format!(
171 "declare function {}(arg0: {}, arg1: {}): {};",
172 fn_name, arg1_name, arg2_name, rt_name
173 )
174 }
175
176 fn to_type_name(&self) -> String {
177 "any".into()
178 }
179}