specta_util/
static_types.rs

1use std::fmt::Debug;
2
3use specta::{datatype::DataType, Generics, Type, TypeCollection};
4
5/// Easily convert a non-Specta type into a Specta compatible type.
6/// This will be typed as `any` in Typescript.
7///
8/// WARNING: When used with `Option<Any<T>>`, Typescript will not prompt you about nullability checks as `any | null` is coalesced to `any` in Typescript.
9///
10/// # Examples
11///
12/// This can be used as a type override.
13/// ```rust
14/// use serde::Serialize;
15/// use specta::{Type, Any};
16///
17/// #[derive(Serialize, Type)]
18/// pub struct Demo {
19///     #[specta(type = Any)]
20///     pub field: String,
21/// }
22/// ```
23///
24/// Or it can be used as a wrapper type.
25/// ```rust
26/// use serde::Serialize;
27/// use specta::{Type, Any};
28///
29/// #[derive(Serialize, Type)]
30/// pub struct Demo {
31///     pub field: Any<String>,
32/// }
33/// ```
34pub struct Any<T = ()>(T);
35
36impl<T> Type for Any<T> {
37    fn inline(_: &mut TypeCollection, _: Generics) -> DataType {
38        DataType::Any
39    }
40}
41
42impl<T: Debug> Debug for Any<T> {
43    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44        f.debug_tuple("Any").field(&self.0).finish()
45    }
46}
47
48impl<T: Clone> Clone for Any<T> {
49    fn clone(&self) -> Self {
50        Self(self.0.clone())
51    }
52}
53
54impl<T: Default> Default for Any<T> {
55    fn default() -> Self {
56        Self(T::default())
57    }
58}
59
60#[cfg(feature = "serde")]
61impl<T: serde::Serialize> serde::Serialize for Any<T> {
62    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
63    where
64        S: serde::Serializer,
65    {
66        T::serialize(&self.0, serializer)
67    }
68}
69
70/// Easily convert a non-Specta type into a Specta compatible type.
71/// This will be typed as `unknown` in Typescript.
72///
73/// # Examples
74///
75/// This can be used as a type override.
76/// ```rust
77/// use serde::Serialize;
78/// use specta::{Type, Unknown};
79///
80/// #[derive(Serialize, Type)]
81/// pub struct Demo {
82///     #[specta(type = Unknown)]
83///     pub field: String,
84/// }
85/// ```
86///
87/// Or it can be used as a wrapper type.
88/// ```rust
89/// use serde::Serialize;
90/// use specta::{Type, Unknown};
91///
92/// #[derive(Serialize, Type)]
93/// pub struct Demo {
94///     pub field: Unknown<String>,
95/// }
96/// ```
97pub struct Unknown<T = ()>(T);
98
99impl<T> Type for Unknown<T> {
100    fn inline(_: &mut TypeCollection, _: Generics) -> DataType {
101        DataType::Unknown
102    }
103}
104
105impl<T: Debug> Debug for Unknown<T> {
106    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
107        f.debug_tuple("Any").field(&self.0).finish()
108    }
109}
110
111impl<T: Clone> Clone for Unknown<T> {
112    fn clone(&self) -> Self {
113        Self(self.0.clone())
114    }
115}
116
117impl<T: Default> Default for Unknown<T> {
118    fn default() -> Self {
119        Self(T::default())
120    }
121}
122
123#[cfg(feature = "serde")]
124impl<T: serde::Serialize> serde::Serialize for Unknown<T> {
125    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
126    where
127        S: serde::Serializer,
128    {
129        T::serialize(&self.0, serializer)
130    }
131}