16 Commits

Author SHA1 Message Date
f456e278cb Update dependencies and bump version 2023-10-02 12:15:52 +02:00
f28ab1afcd Do not sort by form name in first place for now 2023-10-02 12:09:54 +02:00
ae6b8d48e5 Merge pull request #9 from CCC-MF/issue_8
Issue #8: Add sorting by depency for required form references and subforms
2023-09-30 16:27:13 +02:00
1302963b56 Issue #8: Use system library content as equal content
Since system library content is already present in OS database, it is no dependencies to be imported.
2023-09-30 16:09:36 +02:00
6be11a8951 Issue #8: Use field ReferencedDataForm instead of Name 2023-09-30 15:37:09 +02:00
416204b30a Issue #8: Add initial sorting based on form dependencies 2023-09-30 15:06:24 +02:00
86e988c50e Add information about filter option 2023-09-30 13:48:06 +02:00
76de86b685 Add information about dependency and requirement symbols 2023-09-30 13:34:41 +02:00
d0de76770f Sort dependencies and requirements 2023-09-30 13:26:25 +02:00
8cae6ce706 Cleanup Requirement::to_string() 2023-09-30 13:04:47 +02:00
81a0c6204b Move common implementation into Requires trait 2023-09-30 12:11:14 +02:00
21e31f35d1 Change requirement string mapping to match Unterformular implementation 2023-09-30 12:04:45 +02:00
108aae329c Change symbol for subform 2023-09-30 11:58:21 +02:00
1f51d3e994 Show subform entries in tree subcommand 2023-09-28 17:19:14 +02:00
c514005182 Update YAML file for UKM 2023-09-28 02:25:26 +02:00
a127133ba2 Add YAML file for master profile 2023-09-28 00:00:43 +02:00
11 changed files with 347 additions and 130 deletions

38
Cargo.lock generated
View File

@@ -19,9 +19,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
[[package]] [[package]]
name = "anstyle" name = "anstyle"
version = "1.0.3" version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46" checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
[[package]] [[package]]
name = "async-trait" name = "async-trait"
@@ -81,9 +81,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.4.4" version = "4.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136" checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@@ -91,9 +91,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.4.4" version = "4.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56" checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45"
dependencies = [ dependencies = [
"anstyle", "anstyle",
"clap_lex", "clap_lex",
@@ -101,9 +101,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_complete" name = "clap_complete"
version = "4.4.1" version = "4.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4110a1e6af615a9e6d0a36f805d5c99099f8bab9b8042f5bc1fa220a4a89e36f" checksum = "e3ae8ba90b9d8b007efe66e55e48fb936272f5ca00349b5b0e89877520d35ea7"
dependencies = [ dependencies = [
"clap", "clap",
] ]
@@ -198,9 +198,9 @@ checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.14.0" version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12"
[[package]] [[package]]
name = "heck" name = "heck"
@@ -216,9 +216,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.0.0" version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown", "hashbrown",
@@ -244,9 +244,9 @@ checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.6.3" version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
@@ -268,7 +268,7 @@ dependencies = [
[[package]] [[package]]
name = "osc-variant" name = "osc-variant"
version = "0.4.0" version = "0.5.0"
dependencies = [ dependencies = [
"clap", "clap",
"clap_complete", "clap_complete",
@@ -360,9 +360,9 @@ dependencies = [
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.10.7" version = "0.10.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"cpufeatures", "cpufeatures",
@@ -418,9 +418,9 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.1.10" version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
[[package]] [[package]]
name = "unsafe-libyaml" name = "unsafe-libyaml"

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "osc-variant" name = "osc-variant"
version = "0.4.1" version = "0.5.0"
edition = "2021" edition = "2021"
authors = ["Paul-Christian Volkmer <volkmer_p@ukw.de>"] authors = ["Paul-Christian Volkmer <volkmer_p@ukw.de>"]
description = "Anwendung zum Anpassen einer OSC-Datei an einen Standort" description = "Anwendung zum Anpassen einer OSC-Datei an einen Standort"

View File

@@ -16,6 +16,10 @@ unvollständigen Ausgabedateien zu erzeugen.
### Beispiele ### Beispiele
Die folgenden Unterbefehle sind verfügbar
#### `sha256sum`
Das Berechnen der SHA256 Prüfsumme ist mit dem Unterbefehl `sha256sum` auch unter Windows einfach möglich Das Berechnen der SHA256 Prüfsumme ist mit dem Unterbefehl `sha256sum` auch unter Windows einfach möglich
und erzeugt eine Ausgabe analog dem Befehl auf Linux-Systemen: und erzeugt eine Ausgabe analog dem Befehl auf Linux-Systemen:
@@ -23,21 +27,40 @@ und erzeugt eine Ausgabe analog dem Befehl auf Linux-Systemen:
osc-variant sha256sum meine-beispieldatei.osc osc-variant sha256sum meine-beispieldatei.osc
``` ```
#### `list`
Zum Auflisten der Inhalte einer Datei wird folgender Befehl verwendet: Zum Auflisten der Inhalte einer Datei wird folgender Befehl verwendet:
``` ```
osc-variant list meine-beispieldatei.osc osc-variant list meine-beispieldatei.osc
``` ```
Zum Auflisten der Inhalte mit allen Abhängigkeiten, z.B. Daten- und Merkmalkataloge und bei Formularen wird der Befehl Mit der Option `--filter` kann die Ausgabe eingeschränkt werden.
#### `tree`
Zum Auflisten der Inhalte mit allen Abhängigkeiten, z.B. Daten- und Merkmalskataloge und bei Formularen wird der Befehl
`tree` verwendet: `tree` verwendet:
``` ```
osc-variant tree meine-beispieldatei.osc osc-variant tree meine-beispieldatei.osc
``` ```
Abhängigkeiten werden je nach Art gekennzeichnet:
* `+`: Datenkatalog
* `-`: Merkmalskatalog
* `>`: Formularverweis
* `*`: Unterformular
Für Formularverweise und Unterformulare werden dabei die verwendeten Datenkataloge nicht erneut ausgegeben.
Achtung! Dies erzeugt eine sehr umfangreiche Ausgabe. Achtung! Dies erzeugt eine sehr umfangreiche Ausgabe.
Mit der Option `--filter` kann auch hier die Ausgabe eingeschränkt werden.
#### `diff`
Zum Vergleich zweier OSC-Dateien wird der Unterbefehl `diff` verwendet. Zum Vergleich zweier OSC-Dateien wird der Unterbefehl `diff` verwendet.
Der optionale Parameter `--strict` vergleicht auch den Inhalt der OSC-Datei. Der optionale Parameter `--strict` vergleicht auch den Inhalt der OSC-Datei.
Ohne diesen wird nur das Vorhandensein von Inhalten und die Revision verglichen. Ohne diesen wird nur das Vorhandensein von Inhalten und die Revision verglichen.
@@ -52,6 +75,8 @@ bzw.
osc-variant diff meine-beispieldatei.osc andere-beispieldatei.osc --strict osc-variant diff meine-beispieldatei.osc andere-beispieldatei.osc --strict
``` ```
#### `modify`
Zum Anpassen des Inhalts einer Datei: Zum Anpassen des Inhalts einer Datei:
``` ```
@@ -71,9 +96,9 @@ Hierzu ist die Option `--compact` vorgesehen. Es können, je nach Datei, bis zu
#### Filter #### Filter
Bei der Auflistung von Inhalten ist es möglich, die Ausgaben anhand des Namens zu filtern. Bei der Auflistung von Inhalten ist es möglich, die Anzeige für die Unterbefehle `list` und `tree` anhand des Namens zu filtern.
Hierzu ist die Option `--filter=` vorgesehen. Hierzu ist die Option `--filter=` vorgesehen.
Wird diese angewendet, werden nur Inhalte ausgegeben, deren Name die angegebene Zeichenkette beinhalten. Wird diese angewendet, werden nur Inhalte angezeigt, deren Name die angegebene Zeichenkette beinhalten.
#### Sortierung #### Sortierung
@@ -81,7 +106,11 @@ Bei der Auflistung der Inhalte, kann die Option `--sorted` dazu verwendet werden
Die Sortierung erfolgt dabei nach Namen des Katalogs oder des Formulars. Die Sortierung erfolgt dabei nach Namen des Katalogs oder des Formulars.
Beim Modifizieren der Inhalte kann ebenfalls die Option `--sorted` dazu verwendet werden, die Einträge im Anschluss an die Modifikation Beim Modifizieren der Inhalte kann ebenfalls die Option `--sorted` dazu verwendet werden, die Einträge im Anschluss an die Modifikation
nach Namen zu sortieren. nach Namen und für Formulare der Abhängigkeit von Formularverweisen und Unterformularen zu sortieren.
Formulare, die von anderen Formularen in einem Formularverweis oder als Unterformular verwendet werden, werden dabei weiter oben angeordnet,
da Onkostar einen Formularimport sequenziell, ohne Berücksichtigung von Abhängigkeiten, durchführt.
Dies erlaubt eine konsistente Reihenfolge der Einträge, wodurch ein direkter Vergleich mit Vorversionen ermöglicht wird. Dies erlaubt eine konsistente Reihenfolge der Einträge, wodurch ein direkter Vergleich mit Vorversionen ermöglicht wird.
##### Entfernen von Inhalten der Systembibliothek bei Modifikation ##### Entfernen von Inhalten der Systembibliothek bei Modifikation

27
examples/dnpm-master.yml Normal file
View File

@@ -0,0 +1,27 @@
forms:
- name: 'DNPM Klinik/Anamnese'
form_references:
- name: MTB
referenced_data_form: 'OS.Tumorkonferenz'
anzeige_auswahl: 'MTB vom {Datum}'
- name: 'DNPM Therapieplan'
form_references:
- name: referstemtb
referenced_data_form: 'OS.Tumorkonferenz'
anzeige_auswahl: 'MTB vom {Datum}'
- name: reftkhumangenber
referenced_data_form: 'OS.Tumorkonferenz'
anzeige_auswahl: 'MTB vom {Datum}'
- name: reftkreevaluation
referenced_data_form: 'OS.Tumorkonferenz'
anzeige_auswahl: 'MTB vom {Datum}'
- name: 'DNPM UF Einzelempfehlung'
form_references:
- name: mtb
referenced_data_form: 'OS.Tumorkonferenz'
anzeige_auswahl: 'MTB vom {Datum}'
- name: 'DNPM UF Rebiopsie'
form_references:
- name: reftumorkonferenz
referenced_data_form: 'OS.Tumorkonferenz'
anzeige_auswahl: 'MTB vom {Datum}'

View File

@@ -4,6 +4,9 @@ forms:
- name: MTB - name: MTB
referenced_data_form: 'MR.MTB_Anmeldung' referenced_data_form: 'MR.MTB_Anmeldung'
anzeige_auswahl: 'MTB Anmeldung vom {Anmeldedatum}' anzeige_auswahl: 'MTB Anmeldung vom {Anmeldedatum}'
scripts_code: |
setFieldValue('AnmeldedatumMTB', getFieldValue('MTB').MTBTermin);
setFieldValue('WHOGrad', getFieldValue('MTB').WHOGrad);
- name: 'DNPM Therapieplan' - name: 'DNPM Therapieplan'
form_references: form_references:
- name: referstemtb - name: referstemtb

View File

@@ -102,7 +102,8 @@ impl Comparable for DataCatalogue {
impl Requires for DataCatalogue { impl Requires for DataCatalogue {
fn get_required_entries<'a>(&'a self, all: &'a OnkostarEditor) -> Vec<Requirement> { fn get_required_entries<'a>(&'a self, all: &'a OnkostarEditor) -> Vec<Requirement> {
self.entries let mut result = self
.entries
.entry .entry
.iter() .iter()
.filter(|&entry| entry.property_catalogue.is_some()) .filter(|&entry| entry.property_catalogue.is_some())
@@ -116,7 +117,10 @@ impl Requires for DataCatalogue {
Some(contained) => Requirement::PropertyCatalogue(contained), Some(contained) => Requirement::PropertyCatalogue(contained),
None => Requirement::ExternalPropertyCatalogue(entry), None => Requirement::ExternalPropertyCatalogue(entry),
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>();
result.sort_unstable_by_key(|item| item.sorting_key());
result
} }
fn to_requirement_string<'a>(&'a self, all: &'a OnkostarEditor) -> String { fn to_requirement_string<'a>(&'a self, all: &'a OnkostarEditor) -> String {

View File

@@ -22,6 +22,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
use std::cmp::Ordering;
use std::collections::HashSet; use std::collections::HashSet;
use console::style; use console::style;
@@ -252,9 +253,54 @@ impl Comparable for DataForm {
fn get_revision(&self) -> u16 { fn get_revision(&self) -> u16 {
self.revision self.revision
} }
fn compare_by_requirement(a: &Self, b: &Self) -> Ordering {
if a.get_name() == b.get_name()
|| a.is_system_library_content()
|| b.is_system_library_content()
{
return Ordering::Equal;
}
if a.requires_form_reference(&b.get_name()) || a.requires_subform(&b.get_name()) {
return Ordering::Greater;
}
Ordering::Less
}
} }
impl Requires for DataForm { impl Requires for DataForm {
fn requires_form_reference(&self, name: &str) -> bool {
self.entries
.entry
.iter()
.map(|item| {
item.type_ == "formReference"
&& match item.referenced_data_form.as_ref() {
Some(refname) => refname == name,
_ => false,
}
})
.filter(|&it| it)
.last()
.unwrap_or_default()
}
fn requires_subform(&self, name: &str) -> bool {
self.entries
.entry
.iter()
.map(|item| {
item.type_ == "subform"
&& match item.referenced_data_form.as_ref() {
Some(refname) => refname == name,
_ => false,
}
})
.filter(|&it| it)
.last()
.unwrap_or_default()
}
fn get_required_entries<'a>(&'a self, all: &'a OnkostarEditor) -> Vec<Requirement> { fn get_required_entries<'a>(&'a self, all: &'a OnkostarEditor) -> Vec<Requirement> {
let mut result = self let mut result = self
.data_catalogues .data_catalogues
@@ -267,6 +313,7 @@ impl Requires for DataForm {
None => Requirement::ExternalDataCatalogue(entry.to_string()), None => Requirement::ExternalDataCatalogue(entry.to_string()),
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
result.sort_unstable_by_key(|item| item.sorting_key());
let referenced_forms = &mut self let referenced_forms = &mut self
.entries .entries
@@ -287,58 +334,33 @@ impl Requires for DataForm {
}, },
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
referenced_forms.sort_unstable_by_key(|item| item.sorting_key());
result.append(referenced_forms); result.append(referenced_forms);
let sub_forms = &mut self
.entries
.entry
.iter()
.filter(|&entry| entry.get_type() == "subform")
.filter_map(|entry| match &entry.referenced_data_form {
Some(name) => Some(name),
None => None,
})
.collect::<HashSet<_>>()
.into_iter()
.map(|entry| match all.find_data_form(entry.as_str()) {
Some(contained) => Requirement::DataFormSubform(contained),
None => match all.find_unterformular(entry.as_str()) {
Some(contained) => Requirement::UnterformularSubform(contained),
None => Requirement::ExternalUnterformularSubform(entry.to_string()),
},
})
.collect::<Vec<_>>();
sub_forms.sort_unstable_by_key(|item| item.sorting_key());
result.append(sub_forms);
result result
} }
fn to_requirement_string<'a>(&'a self, all: &'a OnkostarEditor) -> String {
format!(
"{}\n{}",
self.to_listed_string(),
self.get_required_entries(all)
.iter()
.map(|entry| match entry {
Requirement::DataCatalogue(x) => {
let inner = x
.get_required_entries(all)
.iter()
.map(|inner_entry| match inner_entry {
Requirement::PropertyCatalogue(y) => Some(y.to_listed_string()),
Requirement::ExternalPropertyCatalogue(name) => Some(format!(
"Merkmalskatalog (-) '{}' - hier nicht enthalten",
style(name).yellow()
)),
_ => None,
})
.filter(Option::is_some)
.map(|item| format!(" - {}\n", item.unwrap()))
.collect::<Vec<_>>()
.join("");
if inner.is_empty() {
Some(format!(" + {}\n", x.to_listed_string()))
} else {
Some(format!(" + {}\n{}", x.to_listed_string(), inner))
}
}
Requirement::ExternalDataCatalogue(_) => {
Some(format!(" + {}\n", entry.to_string()))
}
Requirement::DataFormReference(_)
| Requirement::ExternalDataFormReference(_)
| Requirement::UnterformularReference(_)
| Requirement::ExternalUnterformularReference(_) => {
Some(format!(" > {}\n", entry.to_string()))
}
_ => None,
})
.filter(Option::is_some)
.flatten()
.collect::<Vec<_>>()
.join("")
)
}
} }
impl FolderContent for DataForm { impl FolderContent for DataForm {

View File

@@ -22,10 +22,12 @@
* SOFTWARE. * SOFTWARE.
*/ */
use std::cmp::Ordering;
use std::collections::hash_map::DefaultHasher; use std::collections::hash_map::DefaultHasher;
use std::fmt::Debug; use std::fmt::Debug;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use crate::model::requirements::Requires;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::profile::{FormField, FormReference, Profile}; use crate::profile::{FormField, FormReference, Profile};
@@ -251,6 +253,7 @@ pub trait Listable {
pub trait Sortable { pub trait Sortable {
fn sorting_key(&self) -> String; fn sorting_key(&self) -> String;
fn sorted(&mut self) -> &Self fn sorted(&mut self) -> &Self
where where
Self: Sized, Self: Sized,
@@ -267,6 +270,12 @@ pub trait Comparable: Debug {
format!("{:?}", self).hash(&mut h); format!("{:?}", self).hash(&mut h);
h.finish().to_string() h.finish().to_string()
} }
fn compare_by_requirement(_: &Self, _: &Self) -> Ordering
where
Self: Requires,
{
Ordering::Equal
}
} }
pub trait FormEntry { pub trait FormEntry {

View File

@@ -229,17 +229,25 @@ impl OnkostarEditor {
item.sorted(); item.sorted();
}); });
/*self.editor
.data_form
.sort_unstable_by_key(|e| e.sorting_key());*/
self.editor self.editor
.data_form .data_form
.sort_unstable_by_key(|e| e.sorting_key()); .sort_unstable_by(DataForm::compare_by_requirement);
self.editor.data_form.iter_mut().for_each(|item| { self.editor.data_form.iter_mut().for_each(|item| {
item.sorted(); item.sorted();
}); });
/*self.editor
.unterformular
.sort_unstable_by_key(|e| e.sorting_key());*/
self.editor self.editor
.unterformular .unterformular
.sort_unstable_by_key(|e| e.sorting_key()); .sort_unstable_by(Unterformular::compare_by_requirement);
self.editor.unterformular.iter_mut().for_each(|item| { self.editor.unterformular.iter_mut().for_each(|item| {
item.sorted(); item.sorted();

View File

@@ -27,7 +27,7 @@ use crate::model::data_form::DataForm;
use crate::model::onkostar_editor::OnkostarEditor; use crate::model::onkostar_editor::OnkostarEditor;
use crate::model::property_catalogue::PropertyCatalogue; use crate::model::property_catalogue::PropertyCatalogue;
use crate::model::unterformular::Unterformular; use crate::model::unterformular::Unterformular;
use crate::model::Listable; use crate::model::{Comparable, Listable, Sortable};
#[allow(clippy::enum_variant_names)] #[allow(clippy::enum_variant_names)]
pub enum Requirement<'a> { pub enum Requirement<'a> {
@@ -40,6 +40,31 @@ pub enum Requirement<'a> {
#[allow(dead_code)] #[allow(dead_code)]
ExternalDataFormReference(String), ExternalDataFormReference(String),
ExternalUnterformularReference(String), ExternalUnterformularReference(String),
DataFormSubform(&'a DataForm),
UnterformularSubform(&'a Unterformular),
#[allow(dead_code)]
ExternalDataFormSubform(String),
ExternalUnterformularSubform(String),
}
impl Sortable for Requirement<'_> {
fn sorting_key(&self) -> String {
match self {
Requirement::PropertyCatalogue(item) => item.get_name(),
Requirement::DataCatalogue(item) => item.get_name(),
Requirement::DataFormReference(item) => item.get_name(),
Requirement::UnterformularReference(item) => item.get_name(),
Requirement::DataFormSubform(item) => item.get_name(),
Requirement::UnterformularSubform(item) => item.get_name(),
Requirement::ExternalPropertyCatalogue(name)
| Requirement::ExternalDataCatalogue(name)
| Requirement::ExternalDataFormReference(name)
| Requirement::ExternalDataFormSubform(name)
| Requirement::ExternalUnterformularReference(name)
| Requirement::ExternalUnterformularSubform(name) => name.to_string(),
}
}
} }
impl ToString for Requirement<'_> { impl ToString for Requirement<'_> {
@@ -47,26 +72,92 @@ impl ToString for Requirement<'_> {
match self { match self {
Requirement::PropertyCatalogue(item) => item.to_listed_string(), Requirement::PropertyCatalogue(item) => item.to_listed_string(),
Requirement::DataCatalogue(item) => item.to_listed_string(), Requirement::DataCatalogue(item) => item.to_listed_string(),
Requirement::DataFormReference(item) => item.to_listed_string(),
Requirement::UnterformularReference(item) => item.to_listed_string(),
Requirement::DataFormSubform(item) => item.to_listed_string(),
Requirement::UnterformularSubform(item) => item.to_listed_string(),
Requirement::ExternalPropertyCatalogue(name) => { Requirement::ExternalPropertyCatalogue(name) => {
format!("Merkmalskatalog (-) '{}' - hier nicht enthalten", name) format!("Merkmalskatalog (-) '{}' - hier nicht enthalten", name)
} }
Requirement::ExternalDataCatalogue(name) => { Requirement::ExternalDataCatalogue(name) => {
format!("Datenkatalog (-) '{}' - hier nicht enthalten", name) format!("Datenkatalog (-) '{}' - hier nicht enthalten", name)
} }
Requirement::DataFormReference(item) => item.to_listed_string(), Requirement::ExternalDataFormReference(name)
Requirement::UnterformularReference(item) => item.to_listed_string(), | Requirement::ExternalDataFormSubform(name) => {
Requirement::ExternalDataFormReference(name) => {
format!("Formular (-) '{}' - hier nicht enthalten", name) format!("Formular (-) '{}' - hier nicht enthalten", name)
} }
Requirement::ExternalUnterformularReference(name) => { Requirement::ExternalUnterformularReference(name)
| Requirement::ExternalUnterformularSubform(name) => {
format!("Unterformular (-) '{}' - hier nicht enthalten", name) format!("Unterformular (-) '{}' - hier nicht enthalten", name)
} }
} }
} }
} }
pub trait Requires { pub trait Requires
where
Self: Listable,
{
fn requires_form_reference(&self, _: &str) -> bool {
false
}
fn requires_subform(&self, _: &str) -> bool {
false
}
fn get_required_entries<'a>(&'a self, all: &'a OnkostarEditor) -> Vec<Requirement>; fn get_required_entries<'a>(&'a self, all: &'a OnkostarEditor) -> Vec<Requirement>;
fn to_requirement_string<'a>(&'a self, all: &'a OnkostarEditor) -> String; fn to_requirement_string<'a>(&'a self, all: &'a OnkostarEditor) -> String {
format!(
"{}\n{}",
self.to_listed_string(),
self.get_required_entries(all)
.iter()
.map(|entry| match entry {
Requirement::DataCatalogue(x) => {
let inner = x
.get_required_entries(all)
.iter()
.map(|inner_entry| match inner_entry {
Requirement::PropertyCatalogue(_) => Some(inner_entry.to_string()),
Requirement::ExternalPropertyCatalogue(_) => {
Some(inner_entry.to_string())
}
_ => None,
})
.filter(Option::is_some)
.map(|item| format!(" - {}\n", item.unwrap()))
.collect::<Vec<_>>()
.join("");
if inner.is_empty() {
Some(format!(" + {}\n", x.to_listed_string()))
} else {
Some(format!(" + {}\n{}", x.to_listed_string(), inner))
}
}
Requirement::ExternalDataCatalogue(_) => {
Some(format!(" + {}\n", entry.to_string()))
}
Requirement::DataFormReference(_)
| Requirement::ExternalDataFormReference(_)
| Requirement::UnterformularReference(_)
| Requirement::ExternalUnterformularReference(_) => {
Some(format!(" > {}\n", entry.to_string()))
}
Requirement::DataFormSubform(_)
| Requirement::ExternalDataFormSubform(_)
| Requirement::UnterformularSubform(_)
| Requirement::ExternalUnterformularSubform(_) => {
Some(format!(" * {}\n", entry.to_string()))
}
_ => None,
})
.filter(Option::is_some)
.flatten()
.collect::<Vec<_>>()
.join("")
)
}
} }

View File

@@ -22,6 +22,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
use std::cmp::Ordering;
use std::collections::HashSet; use std::collections::HashSet;
use console::style; use console::style;
@@ -256,9 +257,55 @@ impl Comparable for Unterformular {
fn get_revision(&self) -> u16 { fn get_revision(&self) -> u16 {
self.revision self.revision
} }
fn compare_by_requirement(a: &Self, b: &Self) -> Ordering {
if a.get_name() == b.get_name()
|| a.is_system_library_content()
|| b.is_system_library_content()
{
return Ordering::Equal;
}
if a.requires_form_reference(&b.get_name()) || a.requires_subform(&b.get_name()) {
return Ordering::Greater;
}
Ordering::Less
}
} }
impl Requires for Unterformular { impl Requires for Unterformular {
fn requires_form_reference(&self, name: &str) -> bool {
self.entries
.entry
.iter()
.map(|item| {
item.type_ == "formReference"
&& match item.referenced_data_form.as_ref() {
Some(refname) => refname == name,
_ => false,
}
})
.filter(|&it| it)
.last()
.unwrap_or_default()
}
fn requires_subform(&self, name: &str) -> bool {
self.entries
.entry
.iter()
.map(|item| {
item.type_ == "subform"
&& match item.referenced_data_form.as_ref() {
Some(refname) => refname == name,
_ => false,
}
})
.filter(|&it| it)
.last()
.unwrap_or_default()
}
fn get_required_entries<'a>(&'a self, all: &'a OnkostarEditor) -> Vec<Requirement> { fn get_required_entries<'a>(&'a self, all: &'a OnkostarEditor) -> Vec<Requirement> {
let mut result = self let mut result = self
.data_catalogues .data_catalogues
@@ -271,6 +318,7 @@ impl Requires for Unterformular {
None => Requirement::ExternalDataCatalogue(entry.to_string()), None => Requirement::ExternalDataCatalogue(entry.to_string()),
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
result.sort_unstable_by_key(|item| item.sorting_key());
let referenced_forms = &mut self let referenced_forms = &mut self
.entries .entries
@@ -291,57 +339,33 @@ impl Requires for Unterformular {
}, },
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
referenced_forms.sort_unstable_by_key(|item| item.sorting_key());
result.append(referenced_forms); result.append(referenced_forms);
let sub_forms = &mut self
.entries
.entry
.iter()
.filter(|&entry| entry.get_type() == "subform")
.filter_map(|entry| match &entry.referenced_data_form {
Some(name) => Some(name),
None => None,
})
.collect::<HashSet<_>>()
.into_iter()
.map(|entry| match all.find_data_form(entry.as_str()) {
Some(contained) => Requirement::DataFormSubform(contained),
None => match all.find_unterformular(entry.as_str()) {
Some(contained) => Requirement::UnterformularSubform(contained),
None => Requirement::ExternalUnterformularSubform(entry.to_string()),
},
})
.collect::<Vec<_>>();
sub_forms.sort_unstable_by_key(|item| item.sorting_key());
result.append(sub_forms);
result result
} }
fn to_requirement_string<'a>(&'a self, all: &'a OnkostarEditor) -> String {
format!(
"{}\n{}",
self.to_listed_string(),
self.get_required_entries(all)
.iter()
.map(|entry| match entry {
Requirement::DataCatalogue(x) => {
let inner = x
.get_required_entries(all)
.iter()
.map(|inner_entry| match inner_entry {
Requirement::PropertyCatalogue(_) => Some(inner_entry.to_string()),
Requirement::ExternalPropertyCatalogue(_) => {
Some(inner_entry.to_string())
}
_ => None,
})
.filter(Option::is_some)
.map(|item| format!(" - {}\n", item.unwrap()))
.collect::<Vec<_>>()
.join("");
if inner.is_empty() {
Some(format!(" + {}\n", x.to_listed_string()))
} else {
Some(format!(" + {}\n{}", x.to_listed_string(), inner))
}
}
Requirement::ExternalDataCatalogue(_) => {
Some(format!(" + {}\n", entry.to_string()))
}
Requirement::DataFormReference(_)
| Requirement::ExternalDataFormReference(_)
| Requirement::UnterformularReference(_)
| Requirement::ExternalUnterformularReference(_) => {
Some(format!(" > {}\n", entry.to_string()))
}
_ => None,
})
.filter(Option::is_some)
.flatten()
.collect::<Vec<_>>()
.join("")
)
}
} }
impl FolderContent for Unterformular { impl FolderContent for Unterformular {