1use crate::{
2 emit::TypeDef,
3 type_expr::{
4 DefinedTypeInfo, Ident, NativeTypeInfo, ObjectField, TypeArray,
5 TypeDefinition, TypeExpr, TypeInfo, TypeName, TypeObject, TypeString,
6 TypeTuple, TypeUnion,
7 },
8};
9
10macro_rules! impl_native {
11 ($ty:ty, $ts_ty:literal) => {
12 impl TypeDef for $ty {
13 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
14 r#ref: TypeExpr::ident(Ident($ts_ty)),
15 });
16 }
17 };
18}
19
20#[derive(Debug, Clone)]
23pub struct Blob(pub Vec<u8>);
24
25impl_native!(Blob, "Blob");
26impl_native!(bool, "boolean");
27impl_native!(String, "string");
28impl_native!(str, "string");
29impl_native!(char, "string");
30impl_native!(std::path::PathBuf, "string");
31impl_native!(std::path::Path, "string");
32impl_native!(std::ffi::CString, "string");
33impl_native!(std::ffi::CStr, "string");
34impl_native!(std::ffi::OsString, "string");
35impl_native!(std::ffi::OsStr, "string");
36#[cfg(feature = "json_value")]
37impl_native!(serde_json::Number, "number");
38impl_native!(std::net::IpAddr, "string");
39impl_native!(std::net::Ipv4Addr, "string");
40impl_native!(std::net::Ipv6Addr, "string");
41
42macro_rules! impl_number {
43 ($ty:ty, $name:ident) => {
44 impl TypeDef for $ty {
45 const INFO: TypeInfo = TypeInfo::Defined(DefinedTypeInfo {
46 def: TypeDefinition {
47 docs: None,
48 path: &[],
49 name: Ident(stringify!($name)),
50 generic_vars: &[],
51 def: TypeExpr::ident(Ident("number")),
52 },
53 generic_args: &[],
54 });
55 }
56 };
57}
58
59impl_number!(u8, U8);
60impl_number!(u16, U16);
61impl_number!(u32, U32);
62impl_number!(u64, U64);
63impl_number!(usize, Usize);
64impl_number!(i8, I8);
65impl_number!(i16, I16);
66impl_number!(i32, I32);
67impl_number!(i64, I64);
68impl_number!(isize, Isize);
69impl_number!(std::num::NonZeroU8, NonZeroU8);
70impl_number!(std::num::NonZeroU16, NonZeroU16);
71impl_number!(std::num::NonZeroU32, NonZeroU32);
72impl_number!(std::num::NonZeroU64, NonZeroU64);
73impl_number!(std::num::NonZeroUsize, NonZeroUsize);
74impl_number!(std::num::NonZeroI8, NonZeroI8);
75impl_number!(std::num::NonZeroI16, NonZeroI16);
76impl_number!(std::num::NonZeroI32, NonZeroI32);
77impl_number!(std::num::NonZeroI64, NonZeroI64);
78impl_number!(std::num::NonZeroIsize, NonZeroIsize);
79impl_number!(f32, F32);
80impl_number!(f64, F64);
81
82impl TypeDef for () {
83 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
84 r#ref: TypeExpr::ident(Ident("null")),
85 });
86}
87
88macro_rules! impl_tuple {
89 ($($var:ident),+) => {
90 impl<$($var),+> TypeDef for ($($var,)+)
91 where
92 $($var: TypeDef,)+
93 {
94 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
95 r#ref: TypeExpr::Tuple(TypeTuple {
96 docs: None,
97 elements: &[$(TypeExpr::Ref(&$var::INFO),)+],
98 }),
99 });
100 }
101 };
102}
103
104impl_tuple!(T1);
105impl_tuple!(T1, T2);
106impl_tuple!(T1, T2, T3);
107impl_tuple!(T1, T2, T3, T4);
108impl_tuple!(T1, T2, T3, T4, T5);
109impl_tuple!(T1, T2, T3, T4, T5, T6);
110impl_tuple!(T1, T2, T3, T4, T5, T6, T7);
111impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8);
112impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9);
113impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
114impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);
115impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12);
116impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13);
117impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14);
118impl_tuple!(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15);
119impl_tuple!(
120 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16
121);
122
123impl<T, const N: usize> TypeDef for [T; N]
124where
125 T: TypeDef,
126{
127 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
128 r#ref: TypeExpr::Tuple(TypeTuple {
129 docs: None,
130 elements: &[TypeExpr::Ref(&T::INFO); N],
131 }),
132 });
133}
134
135impl<T> TypeDef for Option<T>
136where
137 T: TypeDef,
138{
139 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
140 r#ref: TypeExpr::Union(TypeUnion {
141 docs: None,
142 members: &[TypeExpr::Ref(&T::INFO), TypeExpr::ident(Ident("null"))],
143 }),
144 });
145}
146
147macro_rules! list_type_info {
148 ($item:ty) => {
149 TypeInfo::Native(NativeTypeInfo {
150 r#ref: TypeExpr::Array(TypeArray {
151 docs: None,
152 item: &TypeExpr::Ref(&<$item>::INFO),
153 }),
154 })
155 };
156}
157
158impl<T> TypeDef for Vec<T>
159where
160 T: TypeDef,
161{
162 const INFO: TypeInfo = list_type_info!(T);
163}
164
165impl<T> TypeDef for [T]
166where
167 T: TypeDef,
168{
169 const INFO: TypeInfo = list_type_info!(T);
170}
171
172macro_rules! set_type_info {
173 ($item:ty) => {
174 TypeInfo::Native(NativeTypeInfo {
175 r#ref: TypeExpr::Array(TypeArray {
176 docs: None,
177 item: &TypeExpr::Ref(&<$item>::INFO),
178 }),
179 })
180 };
181}
182
183impl<T, S> TypeDef for std::collections::HashSet<T, S>
184where
185 T: TypeDef,
186 S: 'static,
187{
188 const INFO: TypeInfo = set_type_info!(T);
189}
190
191impl<T> TypeDef for std::collections::BTreeSet<T>
192where
193 T: TypeDef,
194{
195 const INFO: TypeInfo = set_type_info!(T);
196}
197
198macro_rules! map_type_info {
199 ($key:ty, $value:ty) => {
200 TypeInfo::Native(NativeTypeInfo {
201 r#ref: TypeExpr::Name(TypeName {
202 path: &[],
203 name: Ident("Record"),
204 generic_args: &[
205 TypeExpr::Ref(&<$key>::INFO),
206 TypeExpr::Ref(&<$value>::INFO),
207 ],
208 }),
209 })
210 };
211}
212
213impl<K, V, S> TypeDef for std::collections::HashMap<K, V, S>
214where
215 K: TypeDef,
216 V: TypeDef,
217 S: 'static,
218{
219 const INFO: TypeInfo = map_type_info!(K, V);
220}
221
222impl<K, V> TypeDef for std::collections::BTreeMap<K, V>
223where
224 K: TypeDef,
225 V: TypeDef,
226{
227 const INFO: TypeInfo = map_type_info!(K, V);
228}
229
230#[cfg(feature = "json_value")]
231impl<K, V> TypeDef for serde_json::Map<K, V>
232where
233 K: TypeDef,
234 V: TypeDef,
235{
236 const INFO: TypeInfo = map_type_info!(K, V);
237}
238
239impl<T> TypeDef for &'static T
240where
241 T: TypeDef + ?Sized,
242{
243 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
244 r#ref: TypeExpr::Ref(&T::INFO),
245 });
246}
247
248impl<T> TypeDef for Box<T>
249where
250 T: TypeDef + ?Sized,
251{
252 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
253 r#ref: TypeExpr::Ref(&T::INFO),
254 });
255}
256
257impl<T> TypeDef for std::borrow::Cow<'static, T>
258where
259 T: Clone + TypeDef + ?Sized,
260{
261 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
262 r#ref: TypeExpr::Ref(&T::INFO),
263 });
264}
265
266impl<T> TypeDef for std::marker::PhantomData<T>
267where
268 T: TypeDef + ?Sized,
269{
270 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
271 r#ref: TypeExpr::Ref(&T::INFO),
272 });
273}
274
275impl<T, E> TypeDef for std::result::Result<T, E>
276where
277 T: TypeDef,
278 E: TypeDef,
279{
280 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
281 r#ref: TypeExpr::Union(TypeUnion {
282 docs: None,
283 members: &[
284 TypeExpr::Object(TypeObject {
285 docs: None,
286 index_signature: None,
287 fields: &[ObjectField {
288 docs: None,
289 name: TypeString {
290 docs: None,
291 value: "Ok",
292 },
293 optional: false,
294 r#type: TypeExpr::Ref(&T::INFO),
295 }],
296 }),
297 TypeExpr::Object(TypeObject {
298 docs: None,
299 index_signature: None,
300 fields: &[ObjectField {
301 docs: None,
302 name: TypeString {
303 docs: None,
304 value: "Err",
305 },
306 optional: false,
307 r#type: TypeExpr::Ref(&E::INFO),
308 }],
309 }),
310 ],
311 }),
312 });
313}
314
315#[cfg(feature = "json_value")]
316impl TypeDef for serde_json::Value {
317 const INFO: TypeInfo = TypeInfo::Defined(DefinedTypeInfo {
318 def: TypeDefinition {
319 docs: None,
320 path: &[],
321 name: Ident("JSONValue"),
322 generic_vars: &[],
323 def: TypeExpr::Union(TypeUnion {
324 docs: None,
325 members: &[
326 TypeExpr::ident(Ident("null")),
327 TypeExpr::ident(Ident("boolean")),
328 TypeExpr::ident(Ident("number")),
329 TypeExpr::ident(Ident("string")),
330 TypeExpr::Array(TypeArray {
331 docs: None,
332 item: &TypeExpr::ident(Ident("JSONValue")),
333 }),
334 TypeExpr::Object(TypeObject {
335 docs: None,
336 index_signature: Some(
337 crate::type_expr::IndexSignature {
338 docs: None,
339 name: Ident("key"),
340 value: &TypeExpr::ident(Ident("JSONValue")),
341 },
342 ),
343 fields: &[],
344 }),
345 ],
346 }),
347 },
348 generic_args: &[],
349 });
350}