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

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,39 @@ 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() {
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" && 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> { fn get_required_entries<'a>(&'a self, all: &'a OnkostarEditor) -> Vec<Requirement> {
let mut result = self let mut result = self
.data_catalogues .data_catalogues

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

@ -233,6 +233,10 @@ impl OnkostarEditor {
.data_form .data_form
.sort_unstable_by_key(|e| e.sorting_key()); .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| { self.editor.data_form.iter_mut().for_each(|item| {
item.sorted(); item.sorted();
}); });
@ -241,6 +245,10 @@ impl OnkostarEditor {
.unterformular .unterformular
.sort_unstable_by_key(|e| e.sorting_key()); .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| { self.editor.unterformular.iter_mut().for_each(|item| {
item.sorted(); item.sorted();
}); });

View File

@ -98,6 +98,14 @@ pub trait Requires
where where
Self: Listable, 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 {

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,40 @@ 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() {
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" && 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> { fn get_required_entries<'a>(&'a self, all: &'a OnkostarEditor) -> Vec<Requirement> {
let mut result = self let mut result = self
.data_catalogues .data_catalogues