From 416204b30ad241c5a230f32b197b31da327293a1 Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer Date: Sat, 30 Sep 2023 15:06:24 +0200 Subject: [PATCH 1/3] Issue #8: Add initial sorting based on form dependencies --- README.md | 6 +++++- src/model/data_form.rs | 31 +++++++++++++++++++++++++++++++ src/model/mod.rs | 9 +++++++++ src/model/onkostar_editor.rs | 8 ++++++++ src/model/requirements.rs | 8 ++++++++ src/model/unterformular.rs | 32 ++++++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 98aae33..3d54040 100644 --- a/README.md +++ b/README.md @@ -106,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. 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 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. ##### Entfernen von Inhalten der Systembibliothek bei Modifikation diff --git a/src/model/data_form.rs b/src/model/data_form.rs index 6e863dc..87a219c 100644 --- a/src/model/data_form.rs +++ b/src/model/data_form.rs @@ -22,6 +22,7 @@ * SOFTWARE. */ +use std::cmp::Ordering; use std::collections::HashSet; use console::style; @@ -252,9 +253,39 @@ impl Comparable for DataForm { fn get_revision(&self) -> u16 { self.revision } + + fn compare_by_requirement(a: &Self, b: &Self) -> Ordering { + if a.get_name() == b.get_name() { + 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 { + fn requires_form_reference(&self, name: &str) -> bool { + self.entries + .entry + .iter() + .map(|item| item.type_ == "formReference" && item.name == name) + .filter(|&it| it) + .last() + .unwrap_or_default() + } + fn requires_subform(&self, name: &str) -> bool { + self.entries + .entry + .iter() + .map(|item| item.type_ == "subform" && item.name == name) + .filter(|&it| it) + .last() + .unwrap_or_default() + } fn get_required_entries<'a>(&'a self, all: &'a OnkostarEditor) -> Vec { let mut result = self .data_catalogues diff --git a/src/model/mod.rs b/src/model/mod.rs index 6026157..a0e9548 100644 --- a/src/model/mod.rs +++ b/src/model/mod.rs @@ -22,10 +22,12 @@ * SOFTWARE. */ +use std::cmp::Ordering; use std::collections::hash_map::DefaultHasher; use std::fmt::Debug; use std::hash::{Hash, Hasher}; +use crate::model::requirements::Requires; use serde::{Deserialize, Serialize}; use crate::profile::{FormField, FormReference, Profile}; @@ -251,6 +253,7 @@ pub trait Listable { pub trait Sortable { fn sorting_key(&self) -> String; + fn sorted(&mut self) -> &Self where Self: Sized, @@ -267,6 +270,12 @@ pub trait Comparable: Debug { format!("{:?}", self).hash(&mut h); h.finish().to_string() } + fn compare_by_requirement(_: &Self, _: &Self) -> Ordering + where + Self: Requires, + { + Ordering::Equal + } } pub trait FormEntry { diff --git a/src/model/onkostar_editor.rs b/src/model/onkostar_editor.rs index 03ae9d4..b1fb8ab 100644 --- a/src/model/onkostar_editor.rs +++ b/src/model/onkostar_editor.rs @@ -233,6 +233,10 @@ impl OnkostarEditor { .data_form .sort_unstable_by_key(|e| e.sorting_key()); + self.editor + .data_form + .sort_unstable_by(DataForm::compare_by_requirement); + self.editor.data_form.iter_mut().for_each(|item| { item.sorted(); }); @@ -241,6 +245,10 @@ impl OnkostarEditor { .unterformular .sort_unstable_by_key(|e| e.sorting_key()); + self.editor + .unterformular + .sort_unstable_by(Unterformular::compare_by_requirement); + self.editor.unterformular.iter_mut().for_each(|item| { item.sorted(); }); diff --git a/src/model/requirements.rs b/src/model/requirements.rs index 4a3fb65..4a89379 100644 --- a/src/model/requirements.rs +++ b/src/model/requirements.rs @@ -98,6 +98,14 @@ 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; fn to_requirement_string<'a>(&'a self, all: &'a OnkostarEditor) -> String { diff --git a/src/model/unterformular.rs b/src/model/unterformular.rs index 9459024..915baac 100644 --- a/src/model/unterformular.rs +++ b/src/model/unterformular.rs @@ -22,6 +22,7 @@ * SOFTWARE. */ +use std::cmp::Ordering; use std::collections::HashSet; use console::style; @@ -256,9 +257,40 @@ impl Comparable for Unterformular { fn get_revision(&self) -> u16 { self.revision } + + fn compare_by_requirement(a: &Self, b: &Self) -> Ordering { + if a.get_name() == b.get_name() { + 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 { + fn requires_form_reference(&self, name: &str) -> bool { + self.entries + .entry + .iter() + .map(|item| item.type_ == "formReference" && item.name == name) + .filter(|&it| it) + .last() + .unwrap_or_default() + } + fn requires_subform(&self, name: &str) -> bool { + self.entries + .entry + .iter() + .map(|item| item.type_ == "subform" && item.name == name) + .filter(|&it| it) + .last() + .unwrap_or_default() + } + fn get_required_entries<'a>(&'a self, all: &'a OnkostarEditor) -> Vec { let mut result = self .data_catalogues From 6be11a8951559bc63a8df2a9ca9e508355767686 Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer Date: Sat, 30 Sep 2023 15:37:09 +0200 Subject: [PATCH 2/3] Issue #8: Use field `ReferencedDataForm` instead of `Name` --- src/model/data_form.rs | 16 ++++++++++++++-- src/model/unterformular.rs | 16 ++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/model/data_form.rs b/src/model/data_form.rs index 87a219c..45e5116 100644 --- a/src/model/data_form.rs +++ b/src/model/data_form.rs @@ -272,7 +272,13 @@ impl Requires for DataForm { self.entries .entry .iter() - .map(|item| item.type_ == "formReference" && item.name == name) + .map(|item| { + item.type_ == "formReference" + && match item.referenced_data_form.as_ref() { + Some(refname) => refname == name, + _ => false, + } + }) .filter(|&it| it) .last() .unwrap_or_default() @@ -281,7 +287,13 @@ impl Requires for DataForm { self.entries .entry .iter() - .map(|item| item.type_ == "subform" && item.name == name) + .map(|item| { + item.type_ == "subform" + && match item.referenced_data_form.as_ref() { + Some(refname) => refname == name, + _ => false, + } + }) .filter(|&it| it) .last() .unwrap_or_default() diff --git a/src/model/unterformular.rs b/src/model/unterformular.rs index 915baac..92cc9c5 100644 --- a/src/model/unterformular.rs +++ b/src/model/unterformular.rs @@ -276,7 +276,13 @@ impl Requires for Unterformular { self.entries .entry .iter() - .map(|item| item.type_ == "formReference" && item.name == name) + .map(|item| { + item.type_ == "formReference" + && match item.referenced_data_form.as_ref() { + Some(refname) => refname == name, + _ => false, + } + }) .filter(|&it| it) .last() .unwrap_or_default() @@ -285,7 +291,13 @@ impl Requires for Unterformular { self.entries .entry .iter() - .map(|item| item.type_ == "subform" && item.name == name) + .map(|item| { + item.type_ == "subform" + && match item.referenced_data_form.as_ref() { + Some(refname) => refname == name, + _ => false, + } + }) .filter(|&it| it) .last() .unwrap_or_default() From 1302963b566f1bb082c2a77d585bf31902e791a5 Mon Sep 17 00:00:00 2001 From: Paul-Christian Volkmer Date: Sat, 30 Sep 2023 16:09:36 +0200 Subject: [PATCH 3/3] 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. --- src/model/data_form.rs | 5 ++++- src/model/unterformular.rs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/model/data_form.rs b/src/model/data_form.rs index 45e5116..436ed1a 100644 --- a/src/model/data_form.rs +++ b/src/model/data_form.rs @@ -255,7 +255,10 @@ impl Comparable for DataForm { } fn compare_by_requirement(a: &Self, b: &Self) -> Ordering { - if a.get_name() == b.get_name() { + if a.get_name() == b.get_name() + || a.is_system_library_content() + || b.is_system_library_content() + { return Ordering::Equal; } diff --git a/src/model/unterformular.rs b/src/model/unterformular.rs index 92cc9c5..60d4ceb 100644 --- a/src/model/unterformular.rs +++ b/src/model/unterformular.rs @@ -259,7 +259,10 @@ impl Comparable for Unterformular { } fn compare_by_requirement(a: &Self, b: &Self) -> Ordering { - if a.get_name() == b.get_name() { + if a.get_name() == b.get_name() + || a.is_system_library_content() + || b.is_system_library_content() + { return Ordering::Equal; }