use thisversion::traits::{IntoModel, IntoSchema};
use thisversion::{VersionBoundary, VersionFamily};
#[derive(VersionFamily)]
pub enum DocumentVersions {
V1(DocumentV1),
V2(DocumentV2),
V3(DocumentV3),
}
pub struct DocumentV1 {
pub title: String,
pub body: String,
}
pub struct DocumentV2 {
pub title: String,
pub body: String,
pub archived: bool,
}
impl From<DocumentV1> for DocumentV2 {
fn from(prev: DocumentV1) -> Self {
Self {
title: prev.title,
body: prev.body,
archived: false,
}
}
}
#[derive(VersionBoundary)]
#[thisversion(model = Document)]
pub struct DocumentV3 {
pub title: String,
pub content: String,
pub archived: bool,
}
impl From<DocumentV2> for DocumentV3 {
fn from(prev: DocumentV2) -> Self {
Self {
title: prev.title,
content: prev.body,
archived: prev.archived,
}
}
}
pub struct Document {
pub title: String,
pub content: String,
pub archived: bool,
}
fn main() {
let v1 = DocumentV1 {
title: "Hello".to_owned(),
body: "Hello, world!".to_owned(),
};
let versions = DocumentVersions::V1(v1);
let model = versions.into_model();
assert_eq!(model.title, "Hello");
assert_eq!(model.content, "Hello, world!");
assert!(!model.archived);
let versions = model.into_schema();
assert!(matches!(versions, DocumentVersions::V3(_)));
let model = versions.into_model();
assert_eq!(model.content, "Hello, world!");
}