Compose ordinary source defaults with the reviewed Text workspace
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
mod semantic_source;
|
||||
#[path = "migration_v2/source.rs"]
|
||||
mod v2_source;
|
||||
pub(crate) use crate::source_defaults::Mode as DeclarationFormat;
|
||||
use crate::source_defaults::{self, Context as DefaultContext};
|
||||
use crate::*;
|
||||
use serde_json::{Map, Value};
|
||||
use std::{collections::BTreeMap, fmt};
|
||||
@@ -645,25 +647,34 @@ fn offset_for(source: &str, line: usize, column: usize) -> usize {
|
||||
source.len()
|
||||
}
|
||||
|
||||
/// Canonical output uses persistent aliases and explicit identities. Typed
|
||||
/// nested records are ordinary language fields; JSON documents are not embedded.
|
||||
/// Canonical output uses persistent aliases and explicit identities, omitting
|
||||
/// only values supplied by source defaults. Typed nested records are ordinary
|
||||
/// language fields; JSON documents are not embedded.
|
||||
pub fn format(project: &Project) -> String {
|
||||
let mut out = std::format!(
|
||||
"arcadia {SCHEMA_VERSION};\nproject {} {} id \"{}\" {{\n description {};\n\n",
|
||||
"arcadia {SCHEMA_VERSION};\nproject {} {} id \"{}\" {{\n",
|
||||
project.alias,
|
||||
quote(&project.name),
|
||||
project.id,
|
||||
quote(&project.description)
|
||||
);
|
||||
for (_, declaration) in format_declarations(project) {
|
||||
if !project.description.is_empty() {
|
||||
out.push_str(&std::format!(
|
||||
" description {};\n",
|
||||
quote(&project.description)
|
||||
));
|
||||
}
|
||||
out.push('\n');
|
||||
for (_, declaration) in format_declarations(project, DeclarationFormat::Compact) {
|
||||
out.push_str(&declaration);
|
||||
}
|
||||
out.push_str("}\n");
|
||||
out
|
||||
}
|
||||
|
||||
/// The same typed declaration writer is used by flat and modular source output.
|
||||
pub(crate) fn format_declarations(project: &Project) -> Vec<(Id, String)> {
|
||||
/// Shared typed writer for canonical output and lossless editing. Complete edit
|
||||
/// comparisons retain defaults; emitted declarations and value fragments apply
|
||||
/// only the omission rules valid in their selected source context.
|
||||
pub(crate) fn format_declarations(project: &Project, mode: DeclarationFormat) -> Vec<(Id, String)> {
|
||||
let aliases = project
|
||||
.identities()
|
||||
.into_iter()
|
||||
@@ -675,6 +686,7 @@ pub(crate) fn format_declarations(project: &Project) -> Vec<(Id, String)> {
|
||||
let mut fields = payload(&serde_json::to_value(&e.body).unwrap());
|
||||
fields.insert("description".into(), Value::String(e.description.clone()));
|
||||
fields.insert("parent".into(), serde_json::to_value(e.parent).unwrap());
|
||||
let fields = source_defaults::fields(DefaultContext::Element(e.kind()), &fields, mode);
|
||||
write_declaration(
|
||||
&mut out,
|
||||
&element_word(e.kind(), e.layer()),
|
||||
@@ -690,6 +702,7 @@ pub(crate) fn format_declarations(project: &Project) -> Vec<(Id, String)> {
|
||||
let mut out = String::new();
|
||||
let mut fields = payload(&serde_json::to_value(&r.body).unwrap());
|
||||
fields.insert("description".into(), Value::String(r.description.clone()));
|
||||
let fields = source_defaults::fields(DefaultContext::Relation(r.kind()), &fields, mode);
|
||||
write_declaration(
|
||||
&mut out,
|
||||
&relation_word(r.kind()),
|
||||
@@ -705,6 +718,7 @@ pub(crate) fn format_declarations(project: &Project) -> Vec<(Id, String)> {
|
||||
let mut out = String::new();
|
||||
let mut fields = record_fields(d);
|
||||
fields.remove("nodes");
|
||||
let fields = source_defaults::fields(DefaultContext::Diagram, &fields, mode);
|
||||
write_declaration(
|
||||
&mut out,
|
||||
"diagram",
|
||||
@@ -719,6 +733,7 @@ pub(crate) fn format_declarations(project: &Project) -> Vec<(Id, String)> {
|
||||
let mut out = String::new();
|
||||
let mut fields = record_fields(n);
|
||||
fields.insert("diagram".into(), Value::String(d.id.to_string()));
|
||||
let fields = source_defaults::fields(DefaultContext::Node, &fields, mode);
|
||||
write_declaration(&mut out, "node", &n.alias, None, n.id, &fields, &aliases);
|
||||
declarations.push((n.id, out));
|
||||
}
|
||||
@@ -731,7 +746,7 @@ pub(crate) fn format_declarations(project: &Project) -> Vec<(Id, String)> {
|
||||
&a.alias,
|
||||
Some(&a.name),
|
||||
a.id,
|
||||
&record_fields(a),
|
||||
&source_defaults::fields(DefaultContext::Artifact, &record_fields(a), mode),
|
||||
&aliases,
|
||||
);
|
||||
declarations.push((a.id, out));
|
||||
@@ -744,7 +759,7 @@ pub(crate) fn format_declarations(project: &Project) -> Vec<(Id, String)> {
|
||||
&t.alias,
|
||||
Some(&t.name),
|
||||
t.id,
|
||||
&record_fields(t),
|
||||
&source_defaults::fields(DefaultContext::Trace, &record_fields(t), mode),
|
||||
&aliases,
|
||||
);
|
||||
declarations.push((t.id, out));
|
||||
@@ -1742,7 +1757,9 @@ pub(crate) fn resolve_declarations(
|
||||
*viewpoint = ScenarioViewpoint::MixedLegacy;
|
||||
}
|
||||
let mut body = serde_json::to_value(initial).unwrap();
|
||||
let defaults = if legacy {
|
||||
let defaults = if project.schema_version >= 7 {
|
||||
source_defaults::parser_fields(DefaultContext::Element(kind))
|
||||
} else if legacy {
|
||||
crate::persistence::v3::legacy_defaults(kind)
|
||||
.and_then(|value| value.as_object().cloned())
|
||||
.unwrap_or_else(|| payload(&body))
|
||||
@@ -1799,7 +1816,12 @@ pub(crate) fn resolve_declarations(
|
||||
let mut body =
|
||||
serde_json::to_value(RelationBody::new(kind, Id::nil(), Id::nil()))
|
||||
.unwrap();
|
||||
let merged = merge_fields(payload(&body), fields).map_err(&conversion_error)?;
|
||||
let defaults = if project.schema_version >= 7 {
|
||||
source_defaults::parser_fields(DefaultContext::Relation(kind))
|
||||
} else {
|
||||
payload(&body)
|
||||
};
|
||||
let merged = merge_fields(defaults, fields).map_err(&conversion_error)?;
|
||||
replace_payload(&mut body, merged);
|
||||
let body = serde_json::from_value(body)
|
||||
.map_err(|e| conversion_error(e.to_string()))?;
|
||||
@@ -1824,7 +1846,10 @@ pub(crate) fn resolve_declarations(
|
||||
}
|
||||
let defaults =
|
||||
serde_json::json!({"description":"","layer":"Oa","projection":"Overview","routes":[],"view_options":crate::view_options::ViewOptions::default()});
|
||||
let mut record = merge_fields(defaults.as_object().unwrap().clone(), fields)
|
||||
let defaults = if project.schema_version >= 7 {
|
||||
source_defaults::parser_fields(DefaultContext::Diagram)
|
||||
} else { defaults.as_object().unwrap().clone() };
|
||||
let mut record = merge_fields(defaults, fields)
|
||||
.map_err(&conversion_error)?;
|
||||
header(&mut record, d, true);
|
||||
record.insert("nodes".into(), serde_json::json!({}));
|
||||
@@ -1839,7 +1864,10 @@ pub(crate) fn resolve_declarations(
|
||||
return Err(conversion_error("Missing required field 'element'.".into()));
|
||||
}
|
||||
let defaults = serde_json::json!({"element":null,"position":{"x":0.0,"y":0.0},"size":{"width":224.0,"height":94.0},"collapsed":false,"port_anchors":[]});
|
||||
let mut record = merge_fields(defaults.as_object().unwrap().clone(), fields)
|
||||
let defaults = if project.schema_version >= 7 {
|
||||
source_defaults::parser_fields(DefaultContext::Node)
|
||||
} else { defaults.as_object().unwrap().clone() };
|
||||
let mut record = merge_fields(defaults, fields)
|
||||
.map_err(&conversion_error)?;
|
||||
header(&mut record, d, false);
|
||||
let node: NodePlacement = serde_json::from_value(Value::Object(record))
|
||||
@@ -1851,7 +1879,10 @@ pub(crate) fn resolve_declarations(
|
||||
return Err(conversion_error("Missing required field 'owner'.".into()));
|
||||
}
|
||||
let defaults = serde_json::json!({"description":"","owner":null,"relation":"References","uri":"","revision":null,"fragment":null});
|
||||
let mut record = merge_fields(defaults.as_object().unwrap().clone(), fields)
|
||||
let defaults = if project.schema_version >= 7 {
|
||||
source_defaults::parser_fields(DefaultContext::Artifact)
|
||||
} else { defaults.as_object().unwrap().clone() };
|
||||
let mut record = merge_fields(defaults, fields)
|
||||
.map_err(&conversion_error)?;
|
||||
header(&mut record, d, true);
|
||||
let artifact = serde_json::from_value(Value::Object(record))
|
||||
@@ -1867,7 +1898,10 @@ pub(crate) fn resolve_declarations(
|
||||
}
|
||||
}
|
||||
let defaults = serde_json::json!({"description":"","oa":null,"sa":null,"kind":"Refinement","baseline":null});
|
||||
let mut record = merge_fields(defaults.as_object().unwrap().clone(), fields)
|
||||
let defaults = if project.schema_version >= 7 {
|
||||
source_defaults::parser_fields(DefaultContext::Trace)
|
||||
} else { defaults.as_object().unwrap().clone() };
|
||||
let mut record = merge_fields(defaults, fields)
|
||||
.map_err(&conversion_error)?;
|
||||
header(&mut record, d, true);
|
||||
let trace = if project.schema_version < 5 {
|
||||
|
||||
Reference in New Issue
Block a user