use ix_schema::{FieldChange, Ix, MigrateFrom};
#[derive(Ix)]
#[repr(C)]
struct UserV1 {
id: u32,
name_len: u16,
}
#[derive(Ix)]
#[ix(version = 2, migrate_from = UserV1)]
#[repr(C)]
struct UserV2 {
id: u32,
#[ix(rename_from = "name_len")]
name_length: u16,
#[ix(since = 2, default = 1)]
schema_revision: u8,
#[ix(since = 2, default = false)]
verified: bool,
}
#[test]
fn migrate_lifts_v1_into_v2() {
let v1 = UserV1 {
id: 42,
name_len: 7,
};
let v2 = UserV2::migrate_from(v1);
assert_eq!(v2.id, 42);
assert_eq!(v2.name_length, 7); assert_eq!(v2.schema_revision, 1); assert!(!v2.verified);
}
#[test]
fn manifest_records_the_evolution() {
let m = UserV2::MANIFEST;
assert_eq!(m.schema_version, 2);
assert_eq!(m.evolution.migrates_from, Some(1));
let changes = m.evolution.changes;
assert!(changes.contains(&FieldChange::Renamed {
from: "name_len",
to: "name_length",
}));
assert!(changes.contains(&FieldChange::Added {
name: "schema_revision",
}));
assert!(changes.contains(&FieldChange::Added { name: "verified" }));
}
#[test]
fn with_function_transforms_a_field() {
fn widen(n: u16) -> u32 {
u32::from(n)
}
#[derive(Ix)]
#[repr(C)]
struct CounterV1 {
ticks: u16,
}
#[derive(Ix)]
#[ix(version = 2, migrate_from = CounterV1)]
#[repr(C)]
struct CounterV2 {
#[ix(with = widen)]
ticks: u32,
}
let v2 = CounterV2::migrate_from(CounterV1 { ticks: 300 });
assert_eq!(v2.ticks, 300u32);
assert!(
CounterV2::MANIFEST
.evolution
.changes
.contains(&FieldChange::Transformed { name: "ticks" })
);
}