Skip to main content

specta_typescript/
types.rs

1use std::fmt::Debug;
2
3use specta::{
4    Type, Types,
5    datatype::{DataType, Reference},
6};
7
8use crate::opaque;
9
10/// Cast a Rust type to a Typescript `any` type.
11///
12/// <div class="warning">
13///
14/// **WARNING:** When used with `Option<Any<T>>`, Typescript will not prompt you about nullability checks as `any | null` is coalesced to `any` in Typescript.
15///
16/// </div>
17///
18/// # Examples
19///
20/// This can be used as a type override.
21/// ```rust
22/// use serde::Serialize;
23/// use specta::Type;
24/// use specta_typescript::Any;
25///
26/// #[derive(Serialize, Type)]
27/// pub struct Demo {
28///     #[specta(type = Any)]
29///     pub field: String,
30/// }
31/// ```
32///
33/// Or it can be used as a wrapper type.
34/// ```rust
35/// use serde::Serialize;
36/// use specta::Type;
37/// use specta_typescript::Any;
38///
39/// # #[cfg(feature = "serde")] {
40/// #[derive(Serialize, Type)]
41/// pub struct Demo {
42///     pub field: Any<String>,
43/// }
44/// # }
45/// ```
46pub struct Any<T = ()>(T);
47
48impl<T> Type for Any<T> {
49    fn definition(_: &mut Types) -> DataType {
50        DataType::Reference(Reference::opaque(opaque::Any))
51    }
52}
53
54impl<T: Debug> Debug for Any<T> {
55    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56        f.debug_tuple("Any").field(&self.0).finish()
57    }
58}
59
60impl<T: Clone> Clone for Any<T> {
61    fn clone(&self) -> Self {
62        Self(self.0.clone())
63    }
64}
65
66impl<T: Default> Default for Any<T> {
67    fn default() -> Self {
68        Self(T::default())
69    }
70}
71
72#[cfg(feature = "serde")]
73#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
74impl<T: serde::Serialize> serde::Serialize for Any<T> {
75    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
76    where
77        S: serde::Serializer,
78    {
79        T::serialize(&self.0, serializer)
80    }
81}
82
83#[cfg(feature = "serde")]
84#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
85impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Any<T> {
86    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
87    where
88        D: serde::Deserializer<'de>,
89    {
90        T::deserialize(deserializer).map(Self)
91    }
92}
93
94/// Cast a Rust type to a Typescript `unknown` type.
95///
96/// # Examples
97///
98/// This can be used as a type override.
99/// ```rust
100/// use serde::Serialize;
101/// use specta::Type;
102/// use specta_typescript::Unknown;
103///
104/// #[derive(Serialize, Type)]
105/// pub struct Demo {
106///     #[specta(type = Unknown)]
107///     pub field: String,
108/// }
109/// ```
110///
111/// Or it can be used as a wrapper type.
112/// ```rust
113/// use serde::Serialize;
114/// use specta::Type;
115/// use specta_typescript::Unknown;
116///
117/// # #[cfg(feature = "serde")] {
118/// #[derive(Serialize, Type)]
119/// pub struct Demo {
120///     pub field: Unknown<String>,
121/// }
122/// # }
123/// ```
124pub struct Unknown<T = ()>(T);
125
126impl<T> Type for Unknown<T> {
127    fn definition(_: &mut Types) -> DataType {
128        DataType::Reference(Reference::opaque(opaque::Unknown))
129    }
130}
131
132impl<T: Debug> Debug for Unknown<T> {
133    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134        f.debug_tuple("Any").field(&self.0).finish()
135    }
136}
137
138impl<T: Clone> Clone for Unknown<T> {
139    fn clone(&self) -> Self {
140        Self(self.0.clone())
141    }
142}
143
144impl<T: Default> Default for Unknown<T> {
145    fn default() -> Self {
146        Self(T::default())
147    }
148}
149
150#[cfg(feature = "serde")]
151#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
152impl<T: serde::Serialize> serde::Serialize for Unknown<T> {
153    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
154    where
155        S: serde::Serializer,
156    {
157        T::serialize(&self.0, serializer)
158    }
159}
160
161#[cfg(feature = "serde")]
162#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
163impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Unknown<T> {
164    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
165    where
166        D: serde::Deserializer<'de>,
167    {
168        T::deserialize(deserializer).map(Self)
169    }
170}
171
172/// Cast a Rust type to a Typescript `never` type.
173///
174/// # Examples
175///
176/// This can be used as a type override.
177/// ```rust
178/// use serde::Serialize;
179/// use specta::Type;
180/// use specta_typescript::Never;
181///
182/// #[derive(Serialize, Type)]
183/// pub struct Demo {
184///     #[specta(type = Never)]
185///     pub field: String,
186/// }
187/// ```
188///
189/// Or it can be used as a wrapper type.
190/// ```rust
191/// use serde::Serialize;
192/// use specta::Type;
193/// use specta_typescript::Never;
194///
195/// # #[cfg(feature = "serde")] {
196/// #[derive(Serialize, Type)]
197/// pub struct Demo {
198///     pub field: Never<String>,
199/// }
200/// # }
201/// ```
202pub struct Never<T = ()>(T);
203
204impl<T> Type for Never<T> {
205    fn definition(_: &mut Types) -> DataType {
206        DataType::Reference(Reference::opaque(opaque::Never))
207    }
208}
209
210impl<T: Debug> Debug for Never<T> {
211    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
212        f.debug_tuple("Any").field(&self.0).finish()
213    }
214}
215
216impl<T: Clone> Clone for Never<T> {
217    fn clone(&self) -> Self {
218        Self(self.0.clone())
219    }
220}
221
222impl<T: Default> Default for Never<T> {
223    fn default() -> Self {
224        Self(T::default())
225    }
226}
227
228#[cfg(feature = "serde")]
229#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
230impl<T: serde::Serialize> serde::Serialize for Never<T> {
231    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
232    where
233        S: serde::Serializer,
234    {
235        T::serialize(&self.0, serializer)
236    }
237}
238
239#[cfg(feature = "serde")]
240#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
241impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Never<T> {
242    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
243    where
244        D: serde::Deserializer<'de>,
245    {
246        T::deserialize(deserializer).map(Self)
247    }
248}
249
250/// Cast a Rust type to a Typescript `number` type.
251///
252/// This can be used to opt into exporting BigInt-style Rust integer types as
253/// Typescript `number` when precision loss is acceptable.
254///
255/// # Examples
256///
257/// This can be used as a type override.
258/// ```rust
259/// use serde::Serialize;
260/// use specta::Type;
261/// use specta_typescript::Number;
262///
263/// #[derive(Serialize, Type)]
264/// pub struct Demo {
265///     #[specta(type = Number)]
266///     pub field: i128,
267/// }
268/// ```
269///
270/// Or it can be used as a wrapper type.
271/// ```rust
272/// use serde::Serialize;
273/// use specta::Type;
274/// use specta_typescript::Number;
275///
276/// # #[cfg(feature = "serde")] {
277/// #[derive(Serialize, Type)]
278/// pub struct Demo {
279///     pub field: Number<i128>,
280/// }
281/// # }
282/// ```
283pub struct Number<T = ()>(T);
284
285impl<T> Type for Number<T> {
286    fn definition(_: &mut Types) -> DataType {
287        DataType::Reference(Reference::opaque(opaque::Number))
288    }
289}
290
291impl<T: Debug> Debug for Number<T> {
292    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
293        f.debug_tuple("Number").field(&self.0).finish()
294    }
295}
296
297impl<T: Clone> Clone for Number<T> {
298    fn clone(&self) -> Self {
299        Self(self.0.clone())
300    }
301}
302
303impl<T: Default> Default for Number<T> {
304    fn default() -> Self {
305        Self(T::default())
306    }
307}
308
309#[cfg(feature = "serde")]
310#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
311impl<T: serde::Serialize> serde::Serialize for Number<T> {
312    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
313    where
314        S: serde::Serializer,
315    {
316        T::serialize(&self.0, serializer)
317    }
318}
319
320#[cfg(feature = "serde")]
321#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
322impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for Number<T> {
323    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
324    where
325        D: serde::Deserializer<'de>,
326    {
327        T::deserialize(deserializer).map(Self)
328    }
329}
330
331/// Cast a Rust type to a Typescript `bigint` type.
332///
333/// This can be used to opt into exporting BigInt-style Rust integer types as
334/// Typescript `bigint` when your runtime supports lossless bigint transport.
335///
336/// # Examples
337///
338/// This can be used as a type override.
339/// ```rust
340/// use serde::Serialize;
341/// use specta::Type;
342/// use specta_typescript::BigInt;
343///
344/// #[derive(Serialize, Type)]
345/// pub struct Demo {
346///     #[specta(type = BigInt)]
347///     pub field: i128,
348/// }
349/// ```
350///
351/// Or it can be used as a wrapper type.
352/// ```rust
353/// use serde::Serialize;
354/// use specta::Type;
355/// use specta_typescript::BigInt;
356///
357/// # #[cfg(feature = "serde")] {
358/// #[derive(Serialize, Type)]
359/// pub struct Demo {
360///     pub field: BigInt<i128>,
361/// }
362/// # }
363/// ```
364pub struct BigInt<T = ()>(T);
365
366impl<T> Type for BigInt<T> {
367    fn definition(_: &mut Types) -> DataType {
368        DataType::Reference(Reference::opaque(opaque::BigInt))
369    }
370}
371
372impl<T: Debug> Debug for BigInt<T> {
373    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
374        f.debug_tuple("BigInt").field(&self.0).finish()
375    }
376}
377
378impl<T: Clone> Clone for BigInt<T> {
379    fn clone(&self) -> Self {
380        Self(self.0.clone())
381    }
382}
383
384impl<T: Default> Default for BigInt<T> {
385    fn default() -> Self {
386        Self(T::default())
387    }
388}
389
390#[cfg(feature = "serde")]
391#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
392impl<T: serde::Serialize> serde::Serialize for BigInt<T> {
393    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
394    where
395        S: serde::Serializer,
396    {
397        T::serialize(&self.0, serializer)
398    }
399}
400
401#[cfg(feature = "serde")]
402#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
403impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for BigInt<T> {
404    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
405    where
406        D: serde::Deserializer<'de>,
407    {
408        T::deserialize(deserializer).map(Self)
409    }
410}