use typeshift::typeshift;
#[typeshift]
struct User {
#[validate(length(min = 3))]
name: String,
}
#[typeshift]
enum Role {
Admin,
Member,
Guest,
}
#[typeshift]
struct Envelope<T> {
payload: T,
}
#[typeshift]
#[serde(tag = "kind", content = "data")]
enum Event {
#[serde(rename = "user.created")]
UserCreated {
#[serde(rename = "user_id")]
user_id: u64,
},
}
#[typeshift]
enum CheckedEvent {
UserName(#[validate(length(min = 3))] String),
Nothing,
}
#[test]
fn parse_json_and_validate() {
let user: User = match typeshift::parse_str(r#"{"name":"Ada"}"#) {
Ok(user) => user,
Err(err) => panic!("valid user json should parse: {err}"),
};
assert_eq!(user.name, "Ada");
let err = match typeshift::parse_str::<User>(r#"{"name":"Al"}"#) {
Ok(_) => panic!("short name should fail validation"),
Err(err) => err,
};
match err {
typeshift::TypeShiftError::Validation(_) => {}
typeshift::TypeShiftError::Json(_) => panic!("expected validation error"),
}
}
#[test]
fn to_json_and_schema_work() {
let user = User {
name: "Ada".to_string(),
};
let json = match typeshift::to_json(&user) {
Ok(json) => json,
Err(err) => panic!("serialization should succeed: {err}"),
};
assert_eq!(json, r#"{"name":"Ada"}"#);
let schema = typeshift::schema_json::<User>();
assert_eq!(schema["type"], "object");
}
#[test]
fn enum_support_works() {
let role: Role = match typeshift::parse_str(r#""Admin""#) {
Ok(role) => role,
Err(err) => panic!("enum json should parse: {err}"),
};
match role {
Role::Admin => {}
Role::Member | Role::Guest => panic!("expected admin variant"),
}
let schema = typeshift::schema_json::<Role>();
assert_eq!(schema["type"], "string");
}
#[test]
fn generic_support_works() {
let env: Envelope<User> = match typeshift::parse_str(r#"{"payload":{"name":"Ada"}}"#) {
Ok(value) => value,
Err(err) => panic!("generic payload should parse: {err}"),
};
assert_eq!(env.payload.name, "Ada");
let schema = typeshift::schema_json::<Envelope<User>>();
assert_eq!(schema["type"], "object");
}
#[test]
fn enum_serde_and_schema_attrs_work() {
let event = Event::UserCreated { user_id: 7 };
let json = match typeshift::to_json(&event) {
Ok(json) => json,
Err(err) => panic!("enum serialization should succeed: {err}"),
};
assert_eq!(json, r#"{"kind":"user.created","data":{"user_id":7}}"#);
let parsed: Event = match typeshift::parse_str(&json) {
Ok(value) => value,
Err(err) => panic!("enum deserialization should succeed: {err}"),
};
match parsed {
Event::UserCreated { user_id } => assert_eq!(user_id, 7),
}
let schema = typeshift::schema_json::<Event>();
assert!(schema["oneOf"].is_array());
}
#[test]
fn enum_variant_field_validation_works() {
let valid: CheckedEvent = match typeshift::parse_str(r#"{"UserName":"Ada"}"#) {
Ok(value) => value,
Err(err) => panic!("valid enum payload should parse: {err}"),
};
match valid {
CheckedEvent::UserName(name) => assert_eq!(name, "Ada"),
CheckedEvent::Nothing => panic!("expected UserName variant"),
}
let err = match typeshift::parse_str::<CheckedEvent>(r#"{"UserName":"Al"}"#) {
Ok(_) => panic!("short enum value should fail validation"),
Err(err) => err,
};
match err {
typeshift::TypeShiftError::Validation(_) => {}
typeshift::TypeShiftError::Json(_) => panic!("expected validation error"),
}
}