#[path = "support.rs"]
mod support;
use noyalib::fmt::{Commented, FlowMap, FlowSeq, LitString, SpaceAfter};
use noyalib::{Value, from_str, to_string};
use serde::Serialize;
fn main() {
support::header("noyalib -- preserve");
support::task_with_output("Commented<T>: attach comments during serialization", || {
#[derive(Serialize)]
struct Config {
host: Commented<String>,
port: Commented<u16>,
debug: Commented<bool>,
}
let config = Config {
host: Commented::new("localhost".to_string(), "primary database host"),
port: Commented::new(5432, "default postgres port"),
debug: Commented::new(false, "set true for verbose logging"),
};
let yaml = to_string(&config).unwrap();
yaml.lines().map(|l| l.to_string()).collect()
});
support::task_with_output("SpaceAfter<T>: blank lines between sections", || {
#[derive(Serialize)]
struct Doc {
header: SpaceAfter<String>,
body: String,
}
let doc = Doc {
header: SpaceAfter("# Configuration".to_string()),
body: "content here".to_string(),
};
let yaml = to_string(&doc).unwrap();
yaml.lines().map(|l| l.to_string()).collect()
});
support::task_with_output("FlowSeq/FlowMap: preserve inline style intent", || {
#[derive(Serialize)]
struct Manifest {
tags: FlowSeq<Vec<String>>,
metadata: FlowMap<std::collections::BTreeMap<String, String>>,
description: LitString,
}
let mut meta = std::collections::BTreeMap::new();
let _ = meta.insert("version".into(), "1.0".into());
let _ = meta.insert("author".into(), "team".into());
let manifest = Manifest {
tags: FlowSeq(vec!["yaml".into(), "rust".into()]),
metadata: FlowMap(meta),
description: LitString("Multi-line\ndescription\nhere.\n".into()),
};
let yaml = to_string(&manifest).unwrap();
yaml.lines().map(|l| l.to_string()).collect()
});
support::task_with_output("Tagged values: extensibility hook for CST", || {
let yaml = "!important critical-value\n";
let v: Value = from_str(yaml).unwrap();
let output = to_string(&v).unwrap();
vec![
format!("input: {}", yaml.trim()),
format!("output: {}", output.trim()),
format!("tagged: {}", v.is_tagged()),
"Tags provide structural hooks for future CST metadata.".to_string(),
]
});
support::task_with_output("Limitation: comments stripped during parsing", || {
let yaml = "# Database config\nhost: localhost # primary\nport: 5432\n";
let v: Value = from_str(yaml).unwrap();
let output = to_string(&v).unwrap();
vec![
format!("input lines: {} (with comments)", yaml.lines().count()),
format!(
"output lines: {} (comments stripped)",
output.lines().count()
),
"YAML spec: comments are not part of the data model.".to_string(),
"Full CST preservation planned for v0.0.6 (#20).".to_string(),
]
});
support::task_with_output("CST roadmap (v0.0.6)", || {
vec![
"Today:".to_string(),
" Commented<T> — inject comments on write".to_string(),
" SpaceAfter<T> — control blank lines".to_string(),
" FlowSeq/Map — preserve inline style".to_string(),
" LitStr/FoldStr — preserve block scalar style".to_string(),
" Tagged values — structural extensibility".to_string(),
String::new(),
"v0.0.6 (#20):".to_string(),
" CstDocument — preserves all source bytes".to_string(),
" CstNode — retains comments + whitespace".to_string(),
" Surgical edits — modify one value, keep rest intact".to_string(),
" Full round-trip — read -> modify -> write without loss".to_string(),
]
});
support::summary(6);
}