From 1224f93764029cc3c99583c89fff17b3ddfbcda7 Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer Date: Fri, 2 Jun 2023 23:05:35 +0200 Subject: [PATCH] Check input file for additional entries This will prevent the application from creating output without these additional entities, which would be missing in output. Instead, the application will exit with an error message. --- src/main.rs | 80 ++++++++++++++++----------------- src/model/data_catalogue.rs | 5 +++ src/model/data_form.rs | 4 ++ src/model/mod.rs | 11 +++++ src/model/onkostar_editor.rs | 4 ++ src/model/property_catalogue.rs | 12 +++++ src/model/unterformular.rs | 4 ++ 7 files changed, 80 insertions(+), 40 deletions(-) diff --git a/src/main.rs b/src/main.rs index e95f52a..bec2b28 100644 --- a/src/main.rs +++ b/src/main.rs @@ -41,59 +41,59 @@ mod profile; #[command(author, version, about, long_about = None)] #[command(propagate_version = true, arg_required_else_help(true))] struct Cli { - #[arg( - long = "input", - help = "Eingabedatei" - )] + #[arg(long = "input", help = "Eingabedatei")] input: String, - #[arg( - long = "profile", - help = "Profildatei (Optional)" - )] + #[arg(long = "profile", help = "Profildatei (Optional)")] profile: Option, - #[arg( - long = "output", - help = "Ausgabedatei (Optional)" - )] - output: Option + #[arg(long = "output", help = "Ausgabedatei (Optional)")] + output: Option, } fn main() { let cli = Cli::parse(); - let contents = fs::read_to_string(cli.input) - .expect("Should have been able to read the file"); + let contents = fs::read_to_string(cli.input).expect("Should have been able to read the file"); - let mut data: OnkostarEditor = from_str(contents.as_str()).unwrap(); + if let Ok(mut data) = from_str::(contents.as_str()) { + data.apply_variant(); - data.apply_variant(); + let mut buf = String::new(); - let mut buf = String::new(); + let mut serializer = Serializer::new(&mut buf); + serializer.indent(' ', 2); - let mut serializer = Serializer::new(&mut buf); - serializer.indent(' ', 2); + data.serialize(serializer).expect("Generated XML"); - data.serialize(serializer).expect("Generated XML"); + let output = "\n" + .to_string() + .add( + buf + // Replace ' and " as used in original file + .replace("'", "'") + .replace(""", "\"") + .as_str(), + ); - let output = "\n".to_string() - .add(buf - // Replace ' and " as used in original file - .replace("'", "'") - .replace(""", "\"") - .as_str()); - - match cli.output { - Some(filename) => { - let mut file = OpenOptions::new() - .read(false) - .write(true) - .create(true) - .truncate(true) - .open(filename).unwrap(); - file.write_all(output.as_bytes()).expect("Should have written output file"); - }, - None => { - println!("{}", output) + match cli.output { + Some(filename) => { + let mut file = OpenOptions::new() + .read(false) + .write(true) + .create(true) + .truncate(true) + .open(filename) + .unwrap(); + file.write_all(output.as_bytes()) + .expect("Should have written output file"); + } + None => { + println!("{}", output) + } } + } else { + eprintln!("Kann Eingabedatei nicht lesen!"); + eprintln!( + "Die Datei ist entweder keine OSC-Datei, fehlerhaft oder enthält zusätzliche Inhalte." + ); } } diff --git a/src/model/data_catalogue.rs b/src/model/data_catalogue.rs index ffe432d..eba84c3 100644 --- a/src/model/data_catalogue.rs +++ b/src/model/data_catalogue.rs @@ -27,6 +27,7 @@ use serde::{Deserialize, Serialize}; use crate::model::Ordner; #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct DataCatalogue { #[serde(rename = "Name")] name: String, @@ -55,12 +56,14 @@ pub struct DataCatalogue { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Entries { #[serde(rename = "Entry")] entry: Vec, } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Entry { #[serde(rename = "PropertyCatalogue")] #[serde(skip_serializing_if = "Option::is_none")] @@ -122,12 +125,14 @@ pub struct Entry { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Use { #[serde(rename = "ProgramModule", default)] program_module: Vec, } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct ProgramModule { #[serde(rename = "@program")] program: String, diff --git a/src/model/data_form.rs b/src/model/data_form.rs index 037fa8d..ce0b1d3 100644 --- a/src/model/data_form.rs +++ b/src/model/data_form.rs @@ -28,6 +28,7 @@ use crate::model::Ordner; use crate::model::{Ansichten, Entries, Filter, MenuCategory, PlausibilityRules, Script}; #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct DataForm { #[serde(rename = "DataCatalogues")] data_catalogues: DataCatalogues, @@ -162,12 +163,14 @@ impl DataForm { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct DataCatalogues { #[serde(rename = "DataCatalogue")] data_catalogue: Vec, } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Entry { #[serde(rename = "@parentId")] #[serde(skip_serializing_if = "Option::is_none")] @@ -354,6 +357,7 @@ pub struct Entry { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct DataFormEntries { #[serde(rename = "EntryName")] entry_name: Option>, diff --git a/src/model/mod.rs b/src/model/mod.rs index 2b4aa89..8353f64 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -31,6 +31,7 @@ pub mod property_catalogue; pub mod unterformular; #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Script { #[serde(rename = "Code")] code: String, @@ -39,6 +40,7 @@ pub struct Script { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct PlausibilityRule { #[serde(rename = "Type")] type_: String, @@ -69,12 +71,14 @@ pub struct PlausibilityRule { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Entries { #[serde(rename = "Entry")] entry: Vec, } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Ansicht { #[serde(rename = "Name")] name: String, @@ -101,12 +105,14 @@ pub struct Ansicht { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Ansichten { #[serde(rename = "Ansicht", default)] program_module: Vec, } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct MenuCategory { #[serde(rename = "name")] name: String, @@ -117,6 +123,7 @@ pub struct MenuCategory { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Filter { #[serde(rename = "Condition")] condition: String, @@ -128,6 +135,7 @@ pub struct Filter { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct RefEntries { #[serde(rename = "RefEntry")] #[serde(skip_serializing_if = "Option::is_none")] @@ -135,6 +143,7 @@ pub struct RefEntries { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct PlausibilityRules { #[serde(rename = "PlausibilityRule")] #[serde(skip_serializing_if = "Option::is_none")] @@ -142,12 +151,14 @@ pub struct PlausibilityRules { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Bibliothek { #[serde(rename = "Name")] name: String, } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Ordner { #[serde(rename = "Bibliothek")] bibliothek: Bibliothek, diff --git a/src/model/onkostar_editor.rs b/src/model/onkostar_editor.rs index 2102741..2d2b51e 100644 --- a/src/model/onkostar_editor.rs +++ b/src/model/onkostar_editor.rs @@ -30,6 +30,7 @@ use crate::model::property_catalogue::PropertyCatalogue; use crate::model::unterformular::Unterformular; #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct OnkostarEditor { #[serde(rename = "InfoXML")] info_xml: InfoXML, @@ -49,6 +50,7 @@ impl OnkostarEditor { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct InfoXML { #[serde(rename = "DatumXML")] datum_xml: String, @@ -59,6 +61,7 @@ pub struct InfoXML { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] struct Editor { #[serde(rename = "PropertyCatalogue")] property_catalogue: Vec, @@ -71,6 +74,7 @@ struct Editor { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Bibliothek { #[serde(rename = "Name")] name: String, diff --git a/src/model/property_catalogue.rs b/src/model/property_catalogue.rs index db1c3b7..8507ea5 100644 --- a/src/model/property_catalogue.rs +++ b/src/model/property_catalogue.rs @@ -27,6 +27,7 @@ use serde::{Deserialize, Serialize}; use crate::model::Ordner; #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct PropertyCatalogue { #[serde(rename = "Name")] name: String, @@ -52,6 +53,7 @@ pub struct PropertyCatalogue { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Versions { #[serde(rename = "Version")] #[serde(skip_serializing_if = "Option::is_none")] @@ -59,6 +61,7 @@ pub struct Versions { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Version { #[serde(rename = "VersionNumber")] version_number: u16, @@ -86,12 +89,14 @@ pub struct Version { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct VersionEntries { #[serde(rename = "Entry", default)] content: Vec, } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct VersionEntry { #[serde(rename = "Code")] code: String, @@ -110,12 +115,14 @@ pub struct VersionEntry { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Categories { #[serde(rename = "Category", default)] content: Vec, } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Category { #[serde(rename = "Name")] name: String, @@ -132,12 +139,14 @@ pub struct Category { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct CategoryEntries { #[serde(rename = "CategoryEntry", default)] content: Vec, } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct CategoryEntry { #[serde(rename = "Code")] code: String, @@ -156,6 +165,7 @@ pub struct CategoryEntry { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Abbildung { #[serde(rename = "ZielMKVersionOid")] ziel_mk_version_oid: String, @@ -164,6 +174,7 @@ pub struct Abbildung { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct AbbildungEintrag { #[serde(rename = "Entry-from")] entry_from: AbbildungEntry, @@ -172,6 +183,7 @@ pub struct AbbildungEintrag { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct AbbildungEntry { #[serde(rename = "Code")] code: String, diff --git a/src/model/unterformular.rs b/src/model/unterformular.rs index 261aa9a..66d5eb9 100644 --- a/src/model/unterformular.rs +++ b/src/model/unterformular.rs @@ -28,6 +28,7 @@ use crate::model::Ordner; use crate::model::{Ansichten, Entries, Filter, MenuCategory, PlausibilityRules, Script}; #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Unterformular { #[serde(rename = "DataCatalogues")] data_catalogues: DataCatalogues, @@ -170,12 +171,14 @@ impl Unterformular { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct DataCatalogues { #[serde(rename = "DataCatalogue")] data_catalogue: Vec, } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct Entry { #[serde(rename = "@parentId")] #[serde(skip_serializing_if = "Option::is_none")] @@ -363,6 +366,7 @@ pub struct Entry { } #[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] pub struct DataFormEntries { #[serde(rename = "EntryName")] #[serde(skip_serializing_if = "Option::is_none")]