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!(
119 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15
120);
121impl_tuple!(
122 T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16
123);
124
125impl<T, const N: usize> TypeDef for [T; N]
126where
127 T: TypeDef,
128{
129 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
130 r#ref: TypeExpr::Tuple(TypeTuple {
131 docs: None,
132 elements: &[TypeExpr::Ref(&T::INFO); N],
133 }),
134 });
135}
136
137impl<T> TypeDef for Option<T>
138where
139 T: TypeDef,
140{
141 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
142 r#ref: TypeExpr::Union(TypeUnion {
143 docs: None,
144 members: &[TypeExpr::Ref(&T::INFO), TypeExpr::ident(Ident("null"))],
145 }),
146 });
147}
148
149macro_rules! list_type_info {
150 ($item:ty) => {
151 TypeInfo::Native(NativeTypeInfo {
152 r#ref: TypeExpr::Array(TypeArray {
153 docs: None,
154 item: &TypeExpr::Ref(&<$item>::INFO),
155 }),
156 })
157 };
158}
159
160impl<T> TypeDef for Vec<T>
161where
162 T: TypeDef,
163{
164 const INFO: TypeInfo = list_type_info!(T);
165}
166
167impl<T> TypeDef for [T]
168where
169 T: TypeDef,
170{
171 const INFO: TypeInfo = list_type_info!(T);
172}
173
174macro_rules! set_type_info {
175 ($item:ty) => {
176 TypeInfo::Native(NativeTypeInfo {
177 r#ref: TypeExpr::Array(TypeArray {
178 docs: None,
179 item: &TypeExpr::Ref(&<$item>::INFO),
180 }),
181 })
182 };
183}
184
185impl<T, S> TypeDef for std::collections::HashSet<T, S>
186where
187 T: TypeDef,
188 S: 'static,
189{
190 const INFO: TypeInfo = set_type_info!(T);
191}
192
193impl<T> TypeDef for std::collections::BTreeSet<T>
194where
195 T: TypeDef,
196{
197 const INFO: TypeInfo = set_type_info!(T);
198}
199
200macro_rules! map_type_info {
201 ($key:ty, $value:ty) => {
202 TypeInfo::Native(NativeTypeInfo {
203 r#ref: TypeExpr::Name(TypeName {
204 path: &[],
205 name: Ident("Record"),
206 generic_args: &[
207 TypeExpr::Ref(&<$key>::INFO),
208 TypeExpr::Ref(&<$value>::INFO),
209 ],
210 }),
211 })
212 };
213}
214
215impl<K, V, S> TypeDef for std::collections::HashMap<K, V, S>
216where
217 K: TypeDef,
218 V: TypeDef,
219 S: 'static,
220{
221 const INFO: TypeInfo = map_type_info!(K, V);
222}
223
224impl<K, V> TypeDef for std::collections::BTreeMap<K, V>
225where
226 K: TypeDef,
227 V: TypeDef,
228{
229 const INFO: TypeInfo = map_type_info!(K, V);
230}
231
232#[cfg(feature = "json_value")]
233impl<K, V> TypeDef for serde_json::Map<K, V>
234where
235 K: TypeDef,
236 V: TypeDef,
237{
238 const INFO: TypeInfo = map_type_info!(K, V);
239}
240
241impl<T> TypeDef for &'static T
242where
243 T: TypeDef + ?Sized,
244{
245 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
246 r#ref: TypeExpr::Ref(&T::INFO),
247 });
248}
249
250impl<T> TypeDef for Box<T>
251where
252 T: TypeDef + ?Sized,
253{
254 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
255 r#ref: TypeExpr::Ref(&T::INFO),
256 });
257}
258
259impl<T> TypeDef for std::borrow::Cow<'static, T>
260where
261 T: ToOwned + TypeDef + ?Sized,
262{
263 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
264 r#ref: TypeExpr::Ref(&T::INFO),
265 });
266}
267
268impl<T> TypeDef for std::marker::PhantomData<T>
269where
270 T: TypeDef + ?Sized,
271{
272 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
273 r#ref: TypeExpr::Ref(&T::INFO),
274 });
275}
276
277impl<T, E> TypeDef for std::result::Result<T, E>
278where
279 T: TypeDef,
280 E: TypeDef,
281{
282 const INFO: TypeInfo = TypeInfo::Native(NativeTypeInfo {
283 r#ref: TypeExpr::Union(TypeUnion {
284 docs: None,
285 members: &[
286 TypeExpr::Object(TypeObject {
287 docs: None,
288 index_signature: None,
289 fields: &[ObjectField {
290 docs: None,
291 name: TypeString {
292 docs: None,
293 value: "Ok",
294 },
295 optional: false,
296 r#type: TypeExpr::Ref(&T::INFO),
297 }],
298 }),
299 TypeExpr::Object(TypeObject {
300 docs: None,
301 index_signature: None,
302 fields: &[ObjectField {
303 docs: None,
304 name: TypeString {
305 docs: None,
306 value: "Err",
307 },
308 optional: false,
309 r#type: TypeExpr::Ref(&E::INFO),
310 }],
311 }),
312 ],
313 }),
314 });
315}
316
317#[cfg(feature = "json_value")]
318impl TypeDef for serde_json::Value {
319 const INFO: TypeInfo = TypeInfo::Defined(DefinedTypeInfo {
320 def: TypeDefinition {
321 docs: None,
322 path: &[],
323 name: Ident("JSONValue"),
324 generic_vars: &[],
325 def: TypeExpr::Union(TypeUnion {
326 docs: None,
327 members: &[
328 TypeExpr::ident(Ident("null")),
329 TypeExpr::ident(Ident("boolean")),
330 TypeExpr::ident(Ident("number")),
331 TypeExpr::ident(Ident("string")),
332 TypeExpr::Array(TypeArray {
333 docs: None,
334 item: &TypeExpr::ident(Ident("JSONValue")),
335 }),
336 TypeExpr::Object(TypeObject {
337 docs: None,
338 index_signature: Some(
339 crate::type_expr::IndexSignature {
340 docs: None,
341 name: Ident("key"),
342 value: &TypeExpr::ident(Ident("JSONValue")),
343 },
344 ),
345 fields: &[],
346 }),
347 ],
348 }),
349 },
350 generic_args: &[],
351 });
352}