1
0
mirror of https://github.com/pcvolkmer/osc-variant.git synced 2025-04-19 19:56:50 +00:00

Add subcommands 'list' and 'modify'

This commit is contained in:
Paul-Christian Volkmer 2023-06-03 15:27:09 +02:00
parent 5681b1dee3
commit ca145f5e4b
9 changed files with 290 additions and 48 deletions

104
Cargo.lock generated
View File

@ -60,6 +60,25 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
[[package]]
name = "console"
version = "0.15.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
dependencies = [
"encode_unicode",
"lazy_static",
"libc",
"unicode-width",
"windows-sys",
]
[[package]]
name = "encode_unicode"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
[[package]]
name = "hashbrown"
version = "0.12.3"
@ -88,6 +107,18 @@ version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.144"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1"
[[package]]
name = "memchr"
version = "2.5.0"
@ -105,6 +136,7 @@ name = "osc-variant"
version = "0.1.0"
dependencies = [
"clap",
"console",
"quick-xml",
"serde",
"serde_yaml",
@ -195,12 +227,84 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0"
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "unsafe-libyaml"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1865806a559042e51ab5414598446a5871b561d21b6764f2eabb0dd481d880a6"
[[package]]
name = "windows-sys"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
[[package]]
name = "windows_i686_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
[[package]]
name = "windows_x86_64_gnu"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_msvc"
version = "0.42.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
[[package]]
name = "xml-rs"
version = "0.8.13"

View File

@ -11,3 +11,4 @@ serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9"
quick-xml = { version = "0.28", features = ["escape-html", "serialize"], default-features=false }
xml-rs = "0.8"
console = "0.15"

View File

@ -4,12 +4,35 @@ Anwendung zum Anpassen einer OSC-Datei an einen Standort.
## Funktion
Diese Anwendung passt eine OSC-Datei so an, dass (standortbezogene) Formularvarianten für Formularverweise
Diese Anwendung passt listet die Inhalte eine OSC-Datei auf oder passt sie so an, dass (standortbezogene) Formularvarianten für Formularverweise
verwendet werden.
Hierzu wird die Datei deserialisiert, die entsprechenden Formularfelder ermittelt und die Formularvariante
sowie die Anzeige anhand eines Profils angepasst.
Wird in einer OSC-Datei eine noch nicht bekannte Eigenschaft erkannt, wird die weitere Bearbeitung abgebrochen um keine
unvollständigen Ausgabedateien zu erzeugen.
### Beispiele
Zum Auflisten der Inhalte einer Datei wird folgender Befehl verwendet:
```
osc-variant list meine-beispieldatei.osc
```
Zum Anpassen des Inhalts einer Datei:
```
osc-variant modify meine-beispieldatei.osc --profile ukw-profil.yml --output ukw-beispieldatei.osc
```
Die Parameter `--profile` und `--output` sind optional.
Ohne Profildatei wird die Datei lediglich eingelesen, Leerzeichen am Ende eines XML-Tags entfernt und wieder ausgegeben.
Ohne eine Angabe der Ausgabedatei wird auf die Standardausgabe ausgegeben.
## Profile
Zum Erstellen von Varianten einer OSC-Datei wird eine Profildatei im YAML-Format verwendet.

View File

@ -27,7 +27,7 @@ use std::fs::OpenOptions;
use std::io::Write;
use std::ops::Add;
use clap::Parser;
use clap::{Parser, Subcommand};
use quick_xml::de::from_str;
use quick_xml::se::Serializer;
use serde::Serialize;
@ -41,59 +41,91 @@ 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")]
input: String,
#[arg(long = "profile", help = "Profildatei (Optional)")]
profile: Option<String>,
#[arg(long = "output", help = "Ausgabedatei (Optional)")]
output: Option<String>,
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand)]
enum Command {
#[command(about = "Zeigt alle enthaltenen Kataloge und Formulare mit Revision an.")]
List { inputfile: String },
#[command(about = "Modifiziert die angegebene Datei anhand der Profildatei")]
Modify {
inputfile: String,
#[arg(long = "profile", help = "Profildatei (Optional)")]
profile: Option<String>,
#[arg(long = "output", help = "Ausgabedatei (Optional)")]
outputfile: Option<String>,
},
}
fn main() {
let cli = Cli::parse();
let contents = fs::read_to_string(cli.input).expect("Should have been able to read the file");
match cli.command {
Command::List { inputfile } => {
let contents =
fs::read_to_string(inputfile).expect("Should have been able to read the file");
if let Ok(mut data) = from_str::<OnkostarEditor>(contents.as_str()) {
data.apply_variant();
let mut buf = String::new();
let mut serializer = Serializer::new(&mut buf);
serializer.indent(' ', 2);
data.serialize(serializer).expect("Generated XML");
let output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
.to_string()
.add(
buf
// Replace &apos; and &quot; as used in original file
.replace("&apos;", "'")
.replace("&quot;", "\"")
.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)
if let Ok(mut data) = from_str::<OnkostarEditor>(contents.as_str()) {
data.list_forms()
} else {
eprintln!("Kann Eingabedatei nicht lesen!");
eprintln!(
"Die Datei ist entweder keine OSC-Datei, fehlerhaft oder enthält zusätzliche Inhalte."
);
}
}
Command::Modify {
inputfile,
profile,
outputfile,
} => {
let contents =
fs::read_to_string(inputfile).expect("Should have been able to read the file");
if let Ok(mut data) = from_str::<OnkostarEditor>(contents.as_str()) {
data.apply_variant();
let mut buf = String::new();
let mut serializer = Serializer::new(&mut buf);
serializer.indent(' ', 2);
data.serialize(serializer).expect("Generated XML");
let output = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
.to_string()
.add(
buf
// Replace &apos; and &quot; as used in original file
.replace("&apos;", "'")
.replace("&quot;", "\"")
.as_str(),
);
match outputfile {
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."
);
}
}
} else {
eprintln!("Kann Eingabedatei nicht lesen!");
eprintln!(
"Die Datei ist entweder keine OSC-Datei, fehlerhaft oder enthält zusätzliche Inhalte."
);
}
}

View File

@ -55,6 +55,15 @@ pub struct DataCatalogue {
ordner: Ordner,
}
impl DataCatalogue {
pub fn to_listed_string(&self) -> String {
format!(
"Datenkatalog '{}' in Revision '{}'",
self.name, self.revision
)
}
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct Entries {

View File

@ -160,6 +160,10 @@ impl DataForm {
})
}
}
pub fn to_listed_string(&self) -> String {
format!("Formular '{}' in Revision '{}'", self.name, self.revision)
}
}
#[derive(Serialize, Deserialize, Debug)]

View File

@ -22,6 +22,7 @@
* SOFTWARE.
*/
use console::style;
use serde::{Deserialize, Serialize};
use crate::model::data_catalogue::DataCatalogue;
@ -47,6 +48,49 @@ impl OnkostarEditor {
data_form.apply_variant();
})
}
pub fn list_forms(&self) {
println!(
"{}",
style("In der Datei sind folgende Inhalte gespeichert\n").bold()
);
println!(
"{} {}",
self.editor.property_catalogue.len(),
style("Merkmalskataloge").underlined()
);
self.editor
.property_catalogue
.iter()
.for_each(|data_form| println!("{}", data_form.to_listed_string()));
println!(
"\n{} {}",
self.editor.data_catalogue.len(),
style("Datenkataloge").underlined()
);
self.editor
.data_catalogue
.iter()
.for_each(|data_form| println!("{}", data_form.to_listed_string()));
println!(
"\n{} {}",
self.editor.data_form.len(),
style("Formulare").underlined()
);
self.editor
.data_form
.iter()
.for_each(|data_form| println!("{}", data_form.to_listed_string()));
println!(
"\n{} {}",
self.editor.unterformular.len(),
style("Unterformulare").underlined()
);
self.editor
.unterformular
.iter()
.for_each(|data_form| println!("{}", data_form.to_listed_string()));
}
}
#[derive(Serialize, Deserialize, Debug)]

View File

@ -52,6 +52,15 @@ pub struct PropertyCatalogue {
ordner: Ordner,
}
impl PropertyCatalogue {
pub fn to_listed_string(&self) -> String {
format!(
"Merkmalskatalog '{}' in Revision '{}'",
self.name, self.revision
)
}
}
#[derive(Serialize, Deserialize, Debug)]
#[serde(deny_unknown_fields)]
pub struct Versions {

View File

@ -22,6 +22,7 @@
* SOFTWARE.
*/
use console::style;
use serde::{Deserialize, Serialize};
use crate::model::Ordner;
@ -168,6 +169,21 @@ impl Unterformular {
})
}
}
pub fn to_listed_string(&self) -> String {
if self.hat_unterformulare {
return format!(
"Unterformular '{}' in Revision '{}' {}",
self.name,
self.revision,
style("Unterformular mit Markierung 'hat Unterformulare'!").red()
);
}
format!(
"Unterformular '{}' in Revision '{}'",
self.name, self.revision
)
}
}
#[derive(Serialize, Deserialize, Debug)]