#[path = "support.rs"]
mod support;
use noyalib::{from_str, to_string};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Metadata {
created_by: String,
version: u32,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Document {
title: String,
#[serde(flatten)]
meta: Metadata,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
enum Endpoint {
Simple(String),
Detailed { url: String, timeout: u32 },
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Service {
name: String,
endpoints: Vec<Endpoint>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(tag = "type")]
enum Resource {
#[serde(rename = "database")]
Database { host: String, port: u16 },
#[serde(rename = "cache")]
Cache { host: String, ttl: u32 },
}
fn main() {
support::header("noyalib -- flatten");
support::task_with_output("#[serde(flatten)]: merge fields into parent", || {
let doc = Document {
title: "Design Doc".to_string(),
meta: Metadata {
created_by: "alice".to_string(),
version: 3,
},
};
let yaml = to_string(&doc).unwrap();
let parsed: Document = from_str(&yaml).unwrap();
assert_eq!(doc, parsed);
yaml.lines().map(|l| l.to_string()).collect()
});
support::task_with_output("#[serde(untagged)]: infer variant from shape", || {
let svc = Service {
name: "api".to_string(),
endpoints: vec![
Endpoint::Simple("https://api.example.com".to_string()),
Endpoint::Detailed {
url: "https://api.staging.com".to_string(),
timeout: 30,
},
],
};
let yaml = to_string(&svc).unwrap();
let parsed: Service = from_str(&yaml).unwrap();
assert_eq!(svc, parsed);
yaml.lines().map(|l| l.to_string()).collect()
});
support::task_with_output("#[serde(tag = \"type\")]: discriminator field", || {
let resources = vec![
Resource::Database {
host: "db.local".to_string(),
port: 5432,
},
Resource::Cache {
host: "redis.local".to_string(),
ttl: 300,
},
];
let yaml = to_string(&resources).unwrap();
let parsed: Vec<Resource> = from_str(&yaml).unwrap();
assert_eq!(resources, parsed);
yaml.lines().map(|l| l.to_string()).collect()
});
support::task_with_output("All patterns roundtrip correctly", || {
let doc = Document {
title: "Test".to_string(),
meta: Metadata {
created_by: "bot".to_string(),
version: 1,
},
};
let yaml = to_string(&doc).unwrap();
let rt: Document = from_str(&yaml).unwrap();
vec![
format!("title = {}", rt.title),
format!("created_by = {}", rt.meta.created_by),
format!("version = {}", rt.meta.version),
format!("match = {}", doc == rt),
]
});
support::summary(4);
}