1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
//! Easily export your Rust types to other languages
//!
//! Specta provides a system for type introspection and a set of language exporters which allow you to export your Rust types to other languages!
//!
//! **Currently we only support exporting to [TypeScript](https://www.typescriptlang.org) but work has begun on other languages.**
//!
//! ## Features
//! - Export structs and enums to [Typescript](https://www.typescriptlang.org)
//! - Get function types to use in libraries like [tauri-specta](https://github.com/oscartbeaumont/tauri-specta)
//! - Supports wide range of common crates in Rust ecosystem
//! - Supports type inference - can determine type of `fn demo() -> impl Type`.
//!
//! ## Ecosystem
//!
//! Specta can be used in your application either directly or through a library which simplifies the process of using it.
//!
//! - [rspc](https://github.com/oscartbeaumont/rspc) for easily building end-to-end typesafe APIs
//! - [tauri-specta](https://github.com/oscartbeaumont/tauri-specta) for typesafe Tauri commands
//!
//! ## Example
//! ```rust
//! use specta::{*, ts::*};
//!
//! #[derive(Type)]
//! pub struct MyCustomType {
//! pub my_field: String,
//! }
//!
//! fn main() {
//! assert_eq!(
//! ts::export::<MyCustomType>(&ExportConfiguration::default()).unwrap(),
//! "export type MyCustomType = { my_field: string }".to_string()
//! );
//! }
//! ```
//!
//! ## Supported Libraries
//!
//! If you are using [Prisma Client Rust](https://prisma.brendonovich.dev) you can enable the `rspc` feature on it to allow for Specta support on types coming directly from your database. This includes support for the types created via a selection.
//!
//! ## Feature flags
//! ## Alternatives
//!
//! #### Why not ts-rs?
//!
//! [ts-rs](https://github.com/Aleph-Alpha/ts-rs) is a great library,
//! but it has a few limitations which became a problem when I was building [rspc](https://github.com/oscartbeaumont/rspc).
//! Namely it deals with types individually which means it is not possible to export a type and all of the other types it depends on.
//!
//! #### Why not Typeshare?
//! [Typeshare](https://github.com/1Password/typeshare) is also great, but its approach is fundamentally different.
//! While Specta uses traits and runtime information, Typeshare statically analyzes your Rust
//! files.
//! This results in a loss of information and lack of compatability with types from other crates.
//!
/// Types related to working with [`DataType`](crate::DataType). Exposed for advanced users.
/// Provides the global type store and a method to export them to other languages.
/// Support for exporting Rust functions.
/// Contains [`Type`] and everything related to it, including implementations and helper macros
pub use *;
pub use *;
pub use r#type::*;
/// Implements [`Type`] for a given struct or enum.
///
/// ## Example
///
/// ```rust
/// use specta::Type;
///
/// // Use it on structs
/// #[derive(Type)]
/// pub struct MyCustomStruct {
/// pub name: String,
/// }
///
/// #[derive(Type)]
/// pub struct MyCustomStruct2(String, i32, bool);
///
/// // Use it on enums
/// #[derive(Type)]
/// pub enum MyCustomType {
/// VariantOne,
/// VariantTwo(String, i32),
/// VariantThree { name: String, age: i32 },
/// }
/// ```
pub use Type;
/// This macro is exposed from rspc as a wrapper around [Type] with a correct import path.
/// This is exposed from here so rspc doesn't need a macro package for 4 lines of code.
pub use RSPCType;
/// Generates an implementation to help converting a type into into [`DataType`].
///
/// **This is an advanced feature and should probably be limited to usage in libraries built on top of Specta.**
///
/// This differs from [`Type`] in that you can use other [`DataType`] values
/// at runtime inside the targeted type, providing an easy way to construct types at
/// runtime from other types which are known statically via [`Type`].
///
/// Along with inner data types such as [`ObjectType`] and [`EnumType`], some builtin types
/// can easily be convert to a [`DataType`]:
/// - [`Vec`] will become [`DataType::Enum`]
/// - [`Option`] will become the value it contains or [`LiteralType::None`] if it is [`None`]
/// - [`String`] and [`&str`] will become [`LiteralType::String`]
///
/// # Example
/// ```rust
/// use specta::{datatype::LiteralType, ts, DataType, DataTypeFrom, ObjectType, TupleType};
///
/// #[derive(Clone, DataTypeFrom)]
/// pub struct MyEnum(pub Vec<DataType>);
///
/// #[derive(Clone, DataTypeFrom)]
/// pub struct MyObject {
/// a: Vec<DataType>,
/// }
///
/// //
/// // Enum
/// //
///
/// let val: TupleType = MyEnum(vec![
/// LiteralType::String("A".to_string()).into(),
/// LiteralType::String("B".to_string()).into(),
/// ])
/// .into();
///
/// let anon = val.clone().to_anonymous();
/// let anon = ts::datatype(&Default::default(), &anon).unwrap();
/// assert_eq!(anon, "\"A\" | \"B\"");
///
/// let named = val.to_named("MyEnum");
/// let named_export = ts::export_datatype(&Default::default(), &named).unwrap();
/// assert_eq!(named_export, "export type MyEnum = \"A\" | \"B\"");
///
/// //
/// // Object
/// //
///
/// let val: ObjectType = MyObject {
/// a: vec![
/// LiteralType::String("A".to_string()).into(),
/// LiteralType::String("B".to_string()).into(),
/// ],
/// }
/// .into();
///
/// let anon = val.clone().to_anonymous();
/// let anon = ts::datatype(&Default::default(), &anon).unwrap();
/// assert_eq!(anon, "{ a: \"A\" | \"B\" }");
///
/// let named = val.to_named("MyObject");
/// let named_export = ts::export_datatype(&Default::default(), &named).unwrap();
/// assert_eq!(named_export, "export type MyObject = { a: \"A\" | \"B\" }");
/// ```
pub use DataTypeFrom;
/// Prepares a function to have its types extracted using [`fn_datatype`]
///
/// ## Example
///
/// ```rust
/// #[specta::specta]
/// fn my_function(arg1: i32, arg2: bool) -> &'static str {
/// "Hello World"
/// }
/// ```
pub use specta;
doctest!;