Compose reviewed attachments and State bends with saved Scenario
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
//! Read and validate a saved acceptance fixture without rewriting its source.
|
||||
//! cargo run --locked -p oa-core --example attachment_snapshot -- input.arcadia output.json
|
||||
use oa_core::{persistence, validate_candidate};
|
||||
use std::{fs::OpenOptions, io::Write, path::Path};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args: Vec<_> = std::env::args_os().skip(1).collect();
|
||||
if args.len() != 2 {
|
||||
return Err("Expected input source/JSON and a new output JSON path".into());
|
||||
}
|
||||
let project = persistence::load(Path::new(&args[0]))?;
|
||||
validate_candidate(&project)?;
|
||||
let bytes = serde_json::to_vec_pretty(&project)?;
|
||||
let mut output = OpenOptions::new()
|
||||
.write(true)
|
||||
.create_new(true)
|
||||
.open(&args[1])?;
|
||||
output.write_all(&bytes)?;
|
||||
output.write_all(b"\n")?;
|
||||
output.sync_all()?;
|
||||
println!(
|
||||
"Validated {} objects and {} views; saved a complete Project snapshot",
|
||||
project.identities().len(),
|
||||
project.diagrams.len()
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
//! Read-only saved-State geometry evidence for a predeclared native bend trial.
|
||||
//!
|
||||
//! Usage:
|
||||
//! state_bend_routing_snapshot INPUT.arcadia NEW_OUTPUT.json
|
||||
//!
|
||||
//! Loads and validates the complete Project, then independently projects/routes
|
||||
//! every saved State view through core APIs. The complete Project permits exact
|
||||
//! semantic and presentation comparison; derived geometry permits declaring a
|
||||
//! segment and insertion position before native actions. No desktop command,
|
||||
//! planner, gesture, or pin insertion helper is called. Input is never written;
|
||||
//! output uses create_new and fails rather than overwriting an existing file.
|
||||
//!
|
||||
//! Limits: this shares production core routing, so it is not an independent
|
||||
//! mathematical test of that router, nor evidence of UI picking/gesture success.
|
||||
//! It does not generate expected mutations or adapt an oracle to observed edits.
|
||||
//! The acceptance recipe must declare the intended segment/index/point and exact
|
||||
//! Project mutation before UI execution, and bind this executable/source/input
|
||||
//! and output hashes externally. Warning strings are diagnostic Debug output,
|
||||
//! not a stable interchange schema. Missing/hidden/internal transitions have no
|
||||
//! routed edge; their semantic records remain in the complete Project snapshot.
|
||||
|
||||
use oa_core::{persistence, projection, routing, validate_candidate};
|
||||
use serde_json::json;
|
||||
use std::{fs::OpenOptions, io::Write, path::Path};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let args: Vec<_> = std::env::args_os().skip(1).collect();
|
||||
if args.len() != 2 {
|
||||
return Err("Expected input source/JSON and a new output JSON path".into());
|
||||
}
|
||||
let project = persistence::load(Path::new(&args[0]))?;
|
||||
validate_candidate(&project)?;
|
||||
let mut views = Vec::new();
|
||||
for (diagram_id, diagram) in &project.diagrams {
|
||||
let Some(machine) = diagram.projection.state_machine() else {
|
||||
continue;
|
||||
};
|
||||
let projected = projection::project_diagram(&project, diagram);
|
||||
let routed = routing::route_diagram(&project, diagram, &projected);
|
||||
let edges: Vec<_> = routed
|
||||
.edges
|
||||
.iter()
|
||||
.map(|(edge_id, edge)| {
|
||||
json!({
|
||||
"edge": edge_id,
|
||||
"id": edge.id,
|
||||
"points": edge.points,
|
||||
"pins": edge.pins,
|
||||
"pin_fractions": edge.pin_fractions,
|
||||
"custom_suspended": edge.custom_suspended,
|
||||
"warnings": edge.warnings.iter().map(|warning| format!("{warning:?}")).collect::<Vec<_>>(),
|
||||
"label": {
|
||||
"text": edge.label.text,
|
||||
"fraction": edge.label.fraction,
|
||||
"anchor": edge.label.anchor,
|
||||
"center": edge.label.center,
|
||||
"bounds": {
|
||||
"position": edge.label.bounds.position,
|
||||
"size": edge.label.bounds.size
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
views.push(json!({
|
||||
"diagram": diagram_id,
|
||||
"machine": machine,
|
||||
"projected": projected,
|
||||
"routed_bounds": {
|
||||
"position": routed.bounds.position,
|
||||
"size": routed.bounds.size
|
||||
},
|
||||
"routed_edges": edges
|
||||
}));
|
||||
}
|
||||
// Preserve the canonical typed Project serialization (including f32
|
||||
// formatting). Serializing it through Value directly promotes f32 to f64.
|
||||
let project_json: serde_json::Value = serde_json::from_slice(&serde_json::to_vec(&project)?)?;
|
||||
let snapshot = json!({
|
||||
"schema": "state-bend-routing-snapshot/v1",
|
||||
"project": project_json,
|
||||
"state_views": views
|
||||
});
|
||||
// Finish all reading, validation, routing and serialization before creating
|
||||
// the new evidence file. A failed load cannot leave an apparent snapshot.
|
||||
let mut bytes = serde_json::to_vec_pretty(&snapshot)?;
|
||||
bytes.push(b'\n');
|
||||
let mut output = OpenOptions::new()
|
||||
.write(true)
|
||||
.create_new(true)
|
||||
.open(&args[1])?;
|
||||
output.write_all(&bytes)?;
|
||||
output.sync_all()?;
|
||||
println!(
|
||||
"Validated {} objects and {} saved views; snapshotted {} State views and the complete Project",
|
||||
project.identities().len(),
|
||||
project.diagrams.len(),
|
||||
views.len()
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user