Crate zod

source ·
Expand description

Derive your typescript / Rust interop CI Unsafe Rust forbidden Crates.io version docs.rs docs downloads PRs Welcome

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 the HashMap as a z.map([..]) which represents a Map 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()

bool

z.bool()

char

z.string().length(1)

Option<T>

T.optional()

Result<T, E>

z.union([z.object({ Ok: T }), z.object({ Err: U })])

Vec<T>

z.array(T)

&str

z.string()

String

z.string()

usize

z.number().finite().int().nonnegative()

u8

z.number().finite().int().nonnegative().lte(255)

u16

z.number().finite().int().nonnegative().lte(65535)

u32

z.number().finite().int().nonnegative().lte(4294967295)

u64

z.number().finite().int().nonnegative().lte(18446744073709551615)

u128

z.number().finite().int().nonnegative().lte(340282366920938463463374607431768211455)

i8

z.number().finite().int().lte(127).gte(-128)

i16

z.number().finite().int().lte(32767).gte(-32768)

i32

z.number().finite().int().lte(2147483647).gte(-2147483648)

i64

z.number().finite().int().lte(9223372036854775807).gte(-9223372036854775808)

i128

z.number().finite().int().lte(170141183460469231731687303715884105727).gte(-170141183460469231731687303715884105728)

usize

z.number().finite().int().nonnegative()

isize

z.number().finite().int()

f32

z.number()

f64

z.number()

Box<T>

T

Arc<T>

T

Rc<T>

T

Cow<’static, T>

T

Cell<T>

T

RefCell<T>

T

Mutex<T>

T

Weak<T>

T

PhantomData<T>

T

HashSet<T>

z.set(T)

HashMap<T1, U2>

z.map(T, U)

BTreeSet<T>

z.set(T)

BTreeMap<T1, U2>

z.map(T, U)

Modules

Structs

Enums

Traits

Attribute Macros

Derive Macros