#![cfg(test)]
use pretty_assertions::assert_eq;
use zod::ZodType;
mod test_utils;
use test_utils::*;
#[test]
fn enum_adj_struct() {
test_case! {
#[serde(tag = "type", content = "content")]
enum Test {
A { s: String },
B { num: usize },
}
}
let json = serde_json::to_value(Test::B { num: 123 }).unwrap();
assert_eq!(
json,
serde_json::json!({"type": "B", "content": { "num": 123 }})
);
assert_eq!(
Test::schema(),
discriminated_union(
"type",
&[
adj_tagged("A", object! { s : String::schema() }),
adj_tagged("B", object! { num : usize::schema() }),
],
)
);
assert_eq!(
Test::type_def(),
"{ type: \"A\", content: { s: string } } | { type: \"B\", content: { num: number } }"
);
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_adj_struct_multiple_fields() {
test_case! {
#[serde(tag = "type", content = "content")]
enum Test {
A { s: String, num: usize },
B { num: usize },
}
}
let json = serde_json::to_value(Test::A {
s: String::from("abc"),
num: 123,
})
.unwrap();
assert_eq!(
json,
serde_json::json!({"type": "A", "content": {"s": "abc", "num": 123}})
);
assert_eq!(
Test::schema(),
discriminated_union(
"type",
&[
adj_tagged(
"A",
object! {
s: String::schema(),
num: usize::schema()
}
),
adj_tagged("B", object! { num: usize::schema() }),
]
)
);
assert_eq!(
Test::type_def(),
"{ type: \"A\", content: { s: string, num: number } } | { type: \"B\", content: { num: number } }"
);
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_adj_struct_multiple_fields_single() {
test_case! {
#[serde(tag = "type", content = "content")]
enum Test {
A { s: String, num: usize },
}
}
let json = serde_json::to_value(Test::A {
s: String::new(),
num: 123,
})
.unwrap();
assert_eq!(
json,
serde_json::json!({"type": "A", "content": {"s": "", "num": 123}})
);
assert_eq!(
Test::schema(),
adj_tagged("A", object! { s: String::schema(), num: usize::schema() })
);
assert_eq!(
Test::type_def(),
"{ type: \"A\", content: { s: string, num: number } }"
);
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_adj_tuple() {
test_case! {
#[serde(tag = "type", content = "content")]
enum Test {
A(String),
B(usize),
}
}
let json = serde_json::to_value(Test::B(123)).unwrap();
assert_eq!(json, serde_json::json!({"type": "B", "content": 123}));
assert_eq!(
Test::schema(),
discriminated_union(
"type",
&[
adj_tagged("A", String::schema()),
adj_tagged("B", usize::schema())
]
)
);
assert_eq!(
Test::type_def(),
"{ type: \"A\", content: string } | { type: \"B\", content: number }"
);
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_adj_tuple_multiple_fields() {
test_case! {
#[serde(tag = "type", content = "content")]
enum Test {
A(usize, usize),
B(String),
}
}
let json = serde_json::to_value(Test::A(123, 42)).unwrap();
assert_eq!(json, serde_json::json!({"type": "A", "content": [123, 42]}));
assert_eq!(
Test::schema(),
discriminated_union(
"type",
&[
adj_tagged("A", tuple(&[&usize::schema(), &usize::schema()])),
adj_tagged("B", String::schema())
]
)
);
assert_eq!(
Test::type_def(),
"{ type: \"A\", content: [number, number] } | { type: \"B\", content: string }"
);
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_adj_tuple_multiple_fields_single_variant() {
test_case! {
#[serde(tag = "type", content = "content")]
enum Test {
A(usize, usize),
}
}
let json = serde_json::to_value(Test::A(123, 42)).unwrap();
assert_eq!(json, serde_json::json!({"type": "A", "content": [123, 42]}));
assert_eq!(
Test::schema(),
adj_tagged("A", tuple(&[&usize::schema(), &usize::schema()]))
);
assert_eq!(
Test::type_def(),
"{ type: \"A\", content: [number, number] }"
);
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_adj_tuple_single_variant() {
test_case! {
#[serde(tag = "type", content = "content")]
enum Test {
A(usize),
}
}
let json = serde_json::to_value(Test::A(123)).unwrap();
assert_eq!(json, serde_json::json!({"type": "A", "content": 123}));
assert_eq!(Test::schema(), adj_tagged("A", &usize::schema()));
assert_eq!(Test::type_def(), "{ type: \"A\", content: number }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_adj_unit() {
test_case! {
#[serde(tag = "type", content = "content")]
enum Test {
A,
B,
}
}
let json = serde_json::to_value(Test::B).unwrap();
assert_eq!(json, serde_json::json!({"type": "B"}));
assert_eq!(
Test::schema(),
discriminated_union("type", &[object! {type: A}, object! {type: B}])
);
assert_eq!(Test::type_def(), "{ type: \"A\" } | { type: \"B\" }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_adj_unit_single_variant() {
test_case! {
#[serde(tag = "type", content = "content")]
enum Test {
A,
}
}
let json = serde_json::to_value(Test::A).unwrap();
assert_eq!(json, serde_json::json!({ "type": "A"}));
assert_eq!(Test::schema(), object! { type: A });
assert_eq!(Test::type_def(), "{ type: \"A\" }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_extern_struct() {
test_case! {
enum Test {
A { s: String },
B { num: usize },
}
}
let json = serde_json::to_value(Test::B { num: 123 }).unwrap();
assert_eq!(json, serde_json::json!({"B": {"num": 123}}));
assert_eq!(
Test::schema(),
zod_union(&[
object! { A: object! { s: String::schema() }},
object! { B: object! { num: usize::schema() }}
])
);
assert_eq!(
Test::type_def(),
"{ A: { s: string } } | { B: { num: number } }"
);
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_extern_struct_multiple_fields() {
test_case! {
enum Test {
A { s: String, num: usize },
B { num: usize },
}
}
let json = serde_json::to_value(Test::B { num: 123 }).unwrap();
assert_eq!(json, serde_json::json!({"B": {"num": 123}}));
assert_eq!(
Test::schema(),
zod_union(&[
object! {
A: object! {
s: String::schema(),
num: usize::schema()
}
},
object! {
B: object! {
num: usize::schema()
}
}
])
);
assert_eq!(
Test::type_def(),
"{ A: { s: string, num: number } } | { B: { num: number } }"
);
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_extern_struct_multiple_fields_single_variant() {
test_case! {
enum Test {
A { s: String, num: usize },
}
}
let json = serde_json::to_value(Test::A {
s: String::new(),
num: 123,
})
.unwrap();
assert_eq!(json, serde_json::json!({"A": {"s": "", "num": 123}}));
assert_eq!(
Test::schema(),
object! {
A: object! {
s: String::schema(),
num: usize::schema()
}
}
);
assert_eq!(Test::type_def(), "{ A: { s: string, num: number } }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_extern_tuple() {
test_case! {
enum Test {
A(String),
B(usize),
}
}
let json = serde_json::to_value(Test::B(123)).unwrap();
assert_eq!(json, serde_json::json!({"B": 123}));
assert_eq!(
Test::schema(),
zod_union(&[
object! {
A: String::schema()
},
object! {
B: usize::schema()
}
])
);
assert_eq!(Test::type_def(), "{ A: string } | { B: number }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_extern_tuple_multiple_fields() {
test_case! {
enum Test {
A(usize, usize),
B(String),
}
}
let json = serde_json::to_value(Test::A(123, 42)).unwrap();
assert_eq!(json, serde_json::json!({"A": [123, 42]}));
assert_eq!(
Test::schema(),
zod_union(&[
object! {
A: tuple(&[usize::schema(), usize::schema()])
},
object! {
B: String::schema()
}
])
);
assert_eq!(Test::type_def(), "{ A: [number, number] } | { B: string }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_extern_tuple_multiple_fields_single_variant() {
test_case! {
enum Test {
A(usize, usize),
}
}
let json = serde_json::to_value(Test::A(123, 42)).unwrap();
assert_eq!(json, serde_json::json!({"A": [123, 42]}));
assert_eq!(
Test::schema(),
object! {
A: tuple(&[usize::schema(), usize::schema()])
}
);
assert_eq!(Test::type_def(), "{ A: [number, number] }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_extern_tuple_single_single_field_single_variant() {
test_case! {
enum Test {
A(usize),
}
}
let json = serde_json::to_value(Test::A(123)).unwrap();
assert_eq!(json, serde_json::json!({"A": 123}));
assert_eq!(
Test::schema(),
object! {
A: usize::schema()
}
);
assert_eq!(Test::type_def(), "{ A: number }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_extern_unit() {
test_case! {
enum Test {
A,
B,
}
}
let json = serde_json::to_value(Test::B).unwrap();
assert_eq!(json, serde_json::json!("B"));
assert_eq!(Test::schema(), zod_union(&[A, B]));
assert_eq!(Test::type_def(), "\"A\" | \"B\"");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_extern_unit_single_variant() {
test_case! {
enum Test {
A,
}
}
let json = serde_json::to_value(Test::A).unwrap();
assert_eq!(json, serde_json::json!("A"));
assert_eq!(Test::schema(), A);
assert_eq!(Test::type_def(), "\"A\"");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_intern_struct() {
test_case! {
#[serde(tag = "type")]
enum Test {
A { s: String },
B { num: usize },
}
}
let json = serde_json::to_value(Test::B { num: 123 }).unwrap();
assert_eq!(json, serde_json::json!({"type": "B", "num": 123}));
assert_eq!(
Test::schema(),
discriminated_union(
"type",
&[
object! {
type: A,
s: &String::schema()
},
object! {
type: B,
num: &usize::schema()
}
]
)
);
assert_eq!(
Test::type_def(),
"{ type: \"A\", s: string } | { type: \"B\", num: number }"
);
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_intern_struct_multiple_fields() {
test_case! {
#[serde(tag = "type")]
enum Test {
A { s: String, num: usize },
B { num: usize },
}
}
let json = serde_json::to_value(Test::B { num: 123 }).unwrap();
assert_eq!(json, serde_json::json!({"type": "B", "num": 123}));
assert_eq!(
Test::schema(),
discriminated_union(
"type",
&[
object! {
type: A,
s: &String::schema(),
num: &usize::schema()
},
object! {
type: B,
num: &usize::schema()
}
]
)
);
assert_eq!(
Test::type_def(),
"{ type: \"A\", s: string, num: number } | { type: \"B\", num: number }"
);
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_intern_struct_multiple_fields_single_variant() {
test_case! {
#[serde(tag = "type")]
enum Test {
A { s: String, num: usize },
}
}
let json = serde_json::to_value(Test::A {
s: String::new(),
num: 123,
})
.unwrap();
assert_eq!(json, serde_json::json!({"type": "A", "s": "", "num": 123}));
assert_eq!(
Test::schema(),
object! {
type: A,
s: &String::schema(),
num: &usize::schema()
}
);
assert_eq!(Test::type_def(), "{ type: \"A\", s: string, num: number }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_intern_unit() {
test_case! {
#[serde(tag = "type")]
enum Test {
A,
B,
}
}
let json = serde_json::to_value(Test::B).unwrap();
assert_eq!(json, serde_json::json!({"type": "B"}));
assert_eq!(
Test::schema(),
discriminated_union("type", &[object! { type: A }, object! { type: B }])
);
assert_eq!(Test::type_def(), "{ type: \"A\" } | { type: \"B\" }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_intern_unit_single_variant() {
test_case! {
#[serde(tag = "type")]
enum Test {
A,
}
}
let json = serde_json::to_value(Test::A).unwrap();
assert_eq!(json, serde_json::json!({ "type": "A"}));
assert_eq!(Test::schema(), object! { type: A });
assert_eq!(Test::type_def(), "{ type: \"A\" }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_untagged_struct() {
test_case! {
#[serde(untagged)]
enum Test {
A { s: String },
B { num: usize },
}
}
let json = serde_json::to_value(Test::B { num: 123 }).unwrap();
assert_eq!(json, serde_json::json!({"num": 123}));
assert_eq!(
Test::schema(),
zod_union(&[
object! { s: String::schema() },
object! { num: usize::schema() }
])
);
assert_eq!(Test::type_def(), "{ s: string } | { num: number }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_untagged_struct_multiple_fields() {
test_case! {
#[serde(untagged)]
enum Test {
A { s: String, num: usize },
B { num: usize },
}
}
let json = serde_json::to_value(Test::B { num: 123 }).unwrap();
assert_eq!(json, serde_json::json!({"num": 123}));
assert_eq!(
Test::schema(),
zod_union(&[
object! { s: String::schema(), num: usize::schema() },
object! { num: usize::schema() }
])
);
assert_eq!(
Test::type_def(),
"{ s: string, num: number } | { num: number }"
);
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_untagged_struct_multiple_fields_single_variant() {
test_case! {
#[serde(untagged)]
enum Test {
A { s: String, num: usize },
}
}
let json = serde_json::to_value(Test::A {
s: String::new(),
num: 123,
})
.unwrap();
assert_eq!(json, serde_json::json!({"s": "", "num": 123}));
assert_eq!(
Test::schema(),
object! { s: String::schema(), num: usize::schema() }
);
assert_eq!(Test::type_def(), "{ s: string, num: number }");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_untagged_tuple() {
test_case! {
#[serde(untagged)]
enum Test {
A(String),
B(usize),
}
}
let json = serde_json::to_value(Test::B(123)).unwrap();
assert_eq!(json, serde_json::json!(123));
assert_eq!(
Test::schema(),
zod_union(&[String::schema(), usize::schema()])
);
assert_eq!(Test::type_def(), "string | number");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_untagged_tuple_multiple_fields() {
test_case! {
#[serde(untagged)]
enum Test {
A(usize, usize),
B(String),
}
}
let json = serde_json::to_value(Test::A(123, 42)).unwrap();
assert_eq!(json, serde_json::json!([123, 42]));
assert_eq!(
Test::schema(),
zod_union(&[tuple(&[usize::schema(), usize::schema()]), String::schema()])
);
assert_eq!(Test::type_def(), "[number, number] | string");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_untagged_tuple_multiple_fields_single_variant() {
test_case! {
#[serde(untagged)]
enum Test {
A(usize, usize),
}
}
let json = serde_json::to_value(Test::A(123, 42)).unwrap();
assert_eq!(json, serde_json::json!([123, 42]));
assert_eq!(Test::schema(), tuple(&[usize::schema(), usize::schema()]));
assert_eq!(Test::type_def(), "[number, number]");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_untagged_tuple_single_field_single_variant() {
test_case! {
#[serde(untagged)]
enum Test {
A(usize),
}
}
let json = serde_json::to_value(Test::A(123)).unwrap();
assert_eq!(json, serde_json::json!(123));
assert_eq!(Test::schema(), usize::schema());
assert_eq!(Test::type_def(), "number");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_untagged_unit() {
test_case! {
#[serde(untagged)]
enum Test {
A,
B,
}
}
let json = serde_json::to_value(Test::B).unwrap();
assert_eq!(json, serde_json::json!(null));
assert_eq!(Test::schema(), zod_union(&[NULL, NULL]));
assert_eq!(Test::type_def(), "null | null");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}
#[test]
fn enum_untagged_unit_single_variant() {
test_case! {
#[serde(untagged)]
enum Test {
A,
}
}
let json = serde_json::to_value(Test::A).unwrap();
assert_eq!(json, serde_json::json!(null));
assert_eq!(Test::schema(), NULL);
assert_eq!(Test::type_def(), "null");
assert_eq!(Test::inline().to_string(), "Ns.Test");
}