Files

177 lines
7.1 KiB
Rust
Raw Permalink Normal View History

//! 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()
);
}
}