crates/knut-thund/src/authoring/dsl.rs
//! The thin declarative DSL (feature `dsl`): a RON (Rusty Object Notation)
//! serialization of the [`crate::ir::Pipeline`].
//!
//! This is *not* a second authoring model — it is the IR itself, rendered as
//! human-editable, diffable text. Round-tripping is lossless because both
//! directions go through the IR's `serde` impls. This is what gets
//! warehouse-historized (defs + runs) and what an LLM or a config repo edits.
use crate::error::{Result, ThundError};
use crate::ir::Pipeline;
/// Parse a RON pipeline spec into the IR.
pub fn from_ron(text: &str) -> Result<Pipeline> {
let result: Result<Pipeline> = (|| {
let p: Pipeline = ron::from_str(text).map_err(|e| ThundError::Dsl(e.to_string()))?;
p.validate()?;
Ok(p)
})();
// Emit the DSL parse authoring surface's health into the nornir matrix.
crate::functional_status(
"knut-thund/dsl",
"from_ron",
result.is_ok(),
&match &result {
Ok(p) => p.name.clone(),
Err(e) => e.to_string(),
},
);
result
}
/// Render the IR as a pretty RON pipeline spec.
pub fn to_ron(pipeline: &Pipeline) -> Result<String> {
let result = ron::ser::to_string_pretty(pipeline, ron::ser::PrettyConfig::default())
.map_err(|e| ThundError::Dsl(e.to_string()));
// Emit the DSL render authoring surface's health into the nornir matrix.
crate::functional_status("knut-thund/dsl", "to_ron", result.is_ok(), &pipeline.name);
result
}