Rust checks / check (ubuntu-latest) (push) Canceled after 0s
Rust checks / check (windows-latest) (push) Canceled after 0s
Preserve current core, source, REST, desktop, recovery, documentation and validation work, including AGENTS.md and the development summary. This is a work-in-progress checkpoint: the new compact palette has outstanding compilation errors and native acceptance; earlier passing gates retain their documented scope.
177 lines
7.1 KiB
Rust
177 lines
7.1 KiB
Rust
//! Run once against the frozen schema-6 library, never regenerate with schema7.
|
|
use oa_core::{source_project::*, *};
|
|
use serde::Serialize;
|
|
use serde::ser::{SerializeStruct, Serializer};
|
|
use std::{collections::BTreeSet, fs, path::Path};
|
|
struct Project5<'a>(&'a Project);
|
|
struct Diagram5<'a>(&'a Diagram);
|
|
impl Serialize for Project5<'_> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let p = self.0;
|
|
let diagrams: std::collections::BTreeMap<_, _> =
|
|
p.diagrams.iter().map(|(id, d)| (id, Diagram5(d))).collect();
|
|
let mut s = serializer.serialize_struct("Project", 10)?;
|
|
s.serialize_field("schema_version", &5u32)?;
|
|
s.serialize_field("id", &p.id)?;
|
|
s.serialize_field("alias", &p.alias)?;
|
|
s.serialize_field("name", &p.name)?;
|
|
s.serialize_field("description", &p.description)?;
|
|
s.serialize_field("elements", &p.elements)?;
|
|
s.serialize_field("relations", &p.relations)?;
|
|
s.serialize_field("diagrams", &diagrams)?;
|
|
s.serialize_field("artifact_links", &p.artifact_links)?;
|
|
s.serialize_field("traces", &p.traces)?;
|
|
s.end()
|
|
}
|
|
}
|
|
impl Serialize for Diagram5<'_> {
|
|
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
|
let d = self.0;
|
|
let mut s = serializer.serialize_struct("Diagram", 8)?;
|
|
s.serialize_field("id", &d.id)?;
|
|
s.serialize_field("alias", &d.alias)?;
|
|
s.serialize_field("name", &d.name)?;
|
|
s.serialize_field("description", &d.description)?;
|
|
s.serialize_field("layer", &d.layer)?;
|
|
s.serialize_field("projection", &d.projection)?;
|
|
s.serialize_field("nodes", &d.nodes)?;
|
|
s.serialize_field("routes", &d.routes)?;
|
|
s.end()
|
|
}
|
|
}
|
|
fn alias(p: &Project, name: &str) -> Id {
|
|
p.elements
|
|
.values()
|
|
.find(|e| e.alias == name)
|
|
.map(|e| e.id)
|
|
.or_else(|| p.relations.values().find(|e| e.alias == name).map(|e| e.id))
|
|
.unwrap()
|
|
}
|
|
fn main() {
|
|
assert_eq!(
|
|
SCHEMA_VERSION, 6,
|
|
"fixture writer must use historical core6 library"
|
|
);
|
|
let out = Path::new("crates/oa-desktop/src/recovery/fixtures");
|
|
fs::create_dir_all(out).unwrap();
|
|
let original = persistence::decode(&fs::read("examples/release1/model.json").unwrap()).unwrap();
|
|
for schema in [5, 6] {
|
|
let mut p = original.clone();
|
|
if schema == 5 {
|
|
let mut removed: BTreeSet<_> = p
|
|
.elements
|
|
.values()
|
|
.filter(|e| e.kind() == Kind::ExchangeCategory)
|
|
.map(|e| e.id)
|
|
.collect();
|
|
removed.extend(
|
|
p.relations
|
|
.values()
|
|
.filter(|r| r.kind() == RelationKind::CommunicationMean)
|
|
.map(|r| r.id),
|
|
);
|
|
removed.extend(
|
|
p.relations
|
|
.values()
|
|
.filter(|r| {
|
|
r.kind() == RelationKind::ExchangeAllocation
|
|
&& removed.contains(&r.source())
|
|
})
|
|
.map(|r| r.id)
|
|
.collect::<Vec<_>>(),
|
|
);
|
|
p.elements.retain(|id, _| !removed.contains(id));
|
|
p.relations.retain(|id, _| !removed.contains(id));
|
|
p.traces
|
|
.retain(|_, t| !removed.contains(&t.oa) && !removed.contains(&t.sa));
|
|
for d in p.diagrams.values_mut() {
|
|
d.view_options = Default::default();
|
|
}
|
|
let assess = alias(&p, "oa_assess");
|
|
let repair = alias(&p, "oa_repair");
|
|
let request = alias(&p, "oa_repair_request");
|
|
for name in ["oa_conversation", "oa_full_scenario"] {
|
|
let id = alias(&p, name);
|
|
let Some(SharedBody::Scenario { viewpoint, .. }) =
|
|
p.elements.get_mut(&id).unwrap().shared_mut()
|
|
else {
|
|
panic!()
|
|
};
|
|
*viewpoint = ScenarioViewpoint::OperationalActivity;
|
|
}
|
|
for (name, work) in [
|
|
("oa_caller", assess),
|
|
("oa_responder", repair),
|
|
("oa_outer_controller", assess),
|
|
("oa_outer_technician", repair),
|
|
] {
|
|
let id = alias(&p, name);
|
|
let Some(SharedBody::Lifeline { represented }) =
|
|
p.elements.get_mut(&id).unwrap().shared_mut()
|
|
else {
|
|
panic!()
|
|
};
|
|
*represented = Some(work);
|
|
}
|
|
for name in ["oa_call", "oa_reply"] {
|
|
let id = alias(&p, name);
|
|
let Some(SharedBody::Occurrence {
|
|
body: OccurrenceBody::Exchange { exchange, .. },
|
|
..
|
|
}) = p.elements.get_mut(&id).unwrap().shared_mut()
|
|
else {
|
|
panic!()
|
|
};
|
|
*exchange = Some(request);
|
|
}
|
|
}
|
|
let issues = validation::validate(&p);
|
|
assert!(
|
|
!issues
|
|
.iter()
|
|
.any(|i| i.severity == validation::Severity::Error),
|
|
"{issues:?}"
|
|
);
|
|
let mut bundle = format_bundle(&p);
|
|
if schema == 5 {
|
|
let block = " view_options {\n coverage \"All\";\n exchange_labels \"Name\";\n hidden_edges [];\n participant_categories \"All\";\n relation_kinds \"All\";\n work_categories \"All\";\n work_contexts \"All\";\n };\n";
|
|
let mut removed = 0;
|
|
for text in bundle.files.values_mut() {
|
|
removed += text.matches(block).count();
|
|
*text = text.replace(block, "");
|
|
}
|
|
assert_eq!(removed, p.diagrams.len());
|
|
}
|
|
let entry = bundle.files.get_mut(&bundle.entry).unwrap();
|
|
*entry = entry.replacen(
|
|
"arcadia 6;",
|
|
&format!("// Frozen legacy recovery input 雨.\r\narcadia // profile\r\n {schema};"),
|
|
1,
|
|
);
|
|
let compiled = compile_bundle(&bundle, ProjectLimits::default()).unwrap();
|
|
assert_eq!(compiled.decoded.project, p);
|
|
let bytes = if schema == 5 {
|
|
serde_json::to_vec(&Project5(&p)).unwrap()
|
|
} else {
|
|
serde_json::to_vec(&p).unwrap()
|
|
};
|
|
assert_eq!(persistence::decode(&bytes).unwrap(), p);
|
|
fs::write(out.join(format!("source{schema}-model.json")), &bytes).unwrap();
|
|
fs::write(
|
|
out.join(format!("source{schema}-bundle.json")),
|
|
serde_json::to_string_pretty(&bundle).unwrap() + "\n",
|
|
)
|
|
.unwrap();
|
|
let hash = bytes.iter().fold(0xcbf29ce484222325u64, |h, b| {
|
|
(h ^ u64::from(*b)).wrapping_mul(0x100000001b3)
|
|
});
|
|
println!(
|
|
"source{schema}: files={}, elements={}, relations={}, traces={}, fingerprint={hash:016x}",
|
|
bundle.files.len(),
|
|
p.elements.len(),
|
|
p.relations.len(),
|
|
p.traces.len()
|
|
);
|
|
}
|
|
}
|