use crate::generated::model::StepModel;
use crate::generated::write::Writer;
use crate::header::FileHeader;
struct ApdInfo {
status: &'static str,
name: &'static str,
year: i64,
description: &'static str,
}
const UNIVERSAL_FILE_SCHEMA: &str = "STEPIO_UNIVERSAL";
static UNIVERSAL_APD: ApdInfo = ApdInfo {
status: "not a standard",
name: "stepio_universal",
year: 0,
description: "step-io universal union (non-standard, all-AP superset)",
};
#[must_use]
pub fn write(model: &StepModel) -> String {
wrap_envelope(&Writer::new(model).emit_all(), &model.header)
}
#[doc(hidden)]
#[must_use]
pub fn dump_universal(model: &mut StepModel) -> String {
stamp_apd(model, &UNIVERSAL_APD);
model.header.schema =
crate::parser::schema::identify_schema(&[UNIVERSAL_FILE_SCHEMA.to_string()]);
write(model)
}
fn stamp_apd(model: &mut StepModel, apd: &ApdInfo) {
for x in &mut model.application_protocol_definition_arena.items {
x.status = apd.status.to_string();
x.application_interpreted_model_schema_name = apd.name.to_string();
x.application_protocol_year = apd.year;
}
for ac in &mut model.application_context_arena.items {
ac.application = apd.description.to_string();
}
}
fn header_str(s: &str) -> String {
let mut out = String::with_capacity(s.len() + 2);
out.push('\'');
for ch in s.chars() {
if ch == '\'' {
out.push('\'');
}
out.push(ch);
}
out.push('\'');
out
}
fn header_list(items: &[String]) -> String {
if items.is_empty() {
return "('')".to_owned();
}
let inner = items
.iter()
.map(|s| header_str(s))
.collect::<Vec<_>>()
.join(",");
format!("({inner})")
}
fn wrap_envelope(data_body: &str, header: &FileHeader) -> String {
let schema = header.schema.raw().map_or_else(
|| "''".to_owned(),
|r| {
r.iter()
.map(|s| header_str(s))
.collect::<Vec<_>>()
.join(",")
},
);
format!(
"ISO-10303-21;\nHEADER;\nFILE_DESCRIPTION(({desc}),'2;1');\n\
FILE_NAME({name},{stamp},{authors},{orgs},{pre},{orig},{auth});\n\
FILE_SCHEMA(({schema}));\nENDSEC;\nDATA;\n{data_body}ENDSEC;\nEND-ISO-10303-21;\n",
desc = header_str(&header.description),
name = header_str(&header.file_name),
stamp = header_str(&header.time_stamp),
authors = header_list(&header.authors),
orgs = header_list(&header.organizations),
pre = header_str(&header.preprocessor_version),
orig = header_str(&header.originating_system),
auth = header_str(&header.authorisation),
)
}