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

Issue #8: Add initial sorting based on form dependencies

This commit is contained in:
Paul-Christian Volkmer 2023-09-30 15:06:24 +02:00
parent 86e988c50e
commit 416204b30a
6 changed files with 93 additions and 1 deletions

View File

@ -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

View File

@ -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<Requirement> {
let mut result = self
.data_catalogues

View File

@ -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 {

View File

@ -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();
});

View File

@ -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<Requirement>;
fn to_requirement_string<'a>(&'a self, all: &'a OnkostarEditor) -> String {

View File

@ -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<Requirement> {
let mut result = self
.data_catalogues