byteor_runtime/
spec.rs

1use std::path::Path;
2use std::{error::Error as StdError, fmt::Write as _};
3
4fn format_error_chain(err: &(dyn StdError + 'static)) -> String {
5    let mut out = String::new();
6    let _ = write!(&mut out, "{err}");
7    let mut cur = err.source();
8    while let Some(src) = cur {
9        let _ = write!(&mut out, ": {src}");
10        cur = src.source();
11    }
12    out
13}
14
15pub(crate) fn engine_err_to_string(err: byteor_engine::EngineError) -> String {
16    format_error_chain(&err)
17}
18
19/// Read and decode a v1 `spec.kv` file.
20pub fn read_spec_kv_v1(path: &Path) -> Result<byteor_pipeline_spec::PipelineSpecV1, String> {
21    byteor_engine::read_spec_kv_v1(path).map_err(engine_err_to_string)
22}
23
24/// Validate a v1 `spec.kv` file.
25pub fn validate_spec_kv_v1(path: &Path) -> Result<(), String> {
26    byteor_engine::validate_spec_kv_v1(path).map_err(engine_err_to_string)
27}
28
29/// Return stable v1 describe formatting for a `spec.kv` file.
30pub fn describe_spec_kv_v1(path: &Path) -> Result<String, String> {
31    byteor_engine::describe_spec_kv_v1(path).map_err(engine_err_to_string)
32}
33
34/// Return a minimal Graphviz DOT graph for a v1 `spec.kv` file.
35pub fn dot_spec_kv_v1(path: &Path) -> Result<String, String> {
36    byteor_engine::dot_spec_kv_v1(path).map_err(engine_err_to_string)
37}
38
39/// Return the canonical v1 `kv` encoding for a `spec.kv` file.
40///
41/// This is useful for stable diffs and parity checks.
42pub fn canonical_encode_spec_kv_v1(path: &Path) -> Result<String, String> {
43    let input = std::fs::read_to_string(path).map_err(|e| format!("read spec.kv: {e}"))?;
44    byteor_pipeline_spec::canonicalize_spec_kv_v1(&input).map_err(|e| e.to_string())
45}