Expand description
Derive your typescript
/ Rust
interop
This crate provides integrations with the zod typescript library.
NOTE: This crate is not ready for production yet!
Overview
This crate generates zod bindings for your rust
types and
optionally generates an sdk fully automatically.
Example
#[derive(Namespace)]
struct Ns;
#[derive(Serialize, Deserialize, Zod)]
#[zod(namespace = "Ns")]
struct MyStruct {
port: u16,
data: MyData
}
#[derive(Serialize, Deserialize, Zod)]
#[zod(namespace = "Ns")]
enum MyData {
Hello(String),
World(Vec<usize>)
}
Deriving Zod implements the ZodType trait for you exposing a couple of methods to the typescript/schema representation of your rust types.
Calling MyStruct::schema()
will give you a string with a valid zod schema definition:
z.object({ port: Rs.U16, data: Ns.MyData })
Respectively MyData::schema()
will give you:
z.discriminatedUnion([
z.object({ Hello: Rs.String }),
z.object({ World: z.array(Rs.Usize) })
])
There is also the type_def
method which will give you a typescript type definition:
{ port: Rs.U16, data: Ns.MyData }
and
{ Hello: Rs.String } | { World: [Rs.Usize] }
TODO
-
Codegen for struct style enums
-
implement all missing serde attrs where possible. see: ts-rs
- rename
- rename-all
-
tag
- internally
- externally
- adjacently
- untagged
- skip
- skip_deserializing
- default
- transparent structs
- flatten
-
implement tuple structs as z.tuple()
-
Restrict non-default fields in tuple structs to only come before the first default field
-
create namespace macro
-
RPC macros
-
codegen options (eg. schema prefix/suffix, type prefix/suffix)
-
add a mapping table to README.md
-
write detailed intro
-
write rust-docs
-
Consider to allow the use of generics otherwise force implementors to not have generics
-
RPC ui tests
-
improve diagnostics on rpc (eg. correct spans, better compile time errors)
-
improve macro hygiene
- use crate_name in zod-derive
- const scope where possible
-
add integration tests with jest
-
consider making Result/Option “smart” classes with methods like
unwrap
,map
,is_ok
,is_none
etc. -
make rpc a feature or consider splitting the crates entirely
Consideration?
- flattening a
std::collections::HashMap
onto a struct. This works in serde but not in zod because we represent theHashMap
as az.map([..])
which represents aMap
in ts/js.
Contributing
Contribution is more than welcome. This crate is extensively tested but there are a lot of edge-cases. If you find anything that is not working but should, please let meknow.
Type Overview
z.null()
z.bool()
z.string().length(1)
T.optional()
z.union([z.object({ Ok: T }), z.object({ Err: U })])
z.array(T)
z.string()
z.string()
z.number().finite().int().nonnegative()
z.number().finite().int().nonnegative().lte(255)
z.number().finite().int().nonnegative().lte(65535)
z.number().finite().int().nonnegative().lte(4294967295)
z.number().finite().int().nonnegative().lte(18446744073709551615)
z.number().finite().int().nonnegative().lte(340282366920938463463374607431768211455)
z.number().finite().int().lte(127).gte(-128)
z.number().finite().int().lte(32767).gte(-32768)
z.number().finite().int().lte(2147483647).gte(-2147483648)
z.number().finite().int().lte(9223372036854775807).gte(-9223372036854775808)
z.number().finite().int().lte(170141183460469231731687303715884105727).gte(-170141183460469231731687303715884105728)
z.number().finite().int().nonnegative()
z.number().finite().int()
z.number()
z.number()
T
T
T
T
T
T
T
T
T
z.set(T)
z.map(T, U)
z.set(T)
z.map(T, U)
Modules
- Generate the type-table.md