second draft of lawbuilder

This commit is contained in:
philipp 2023-11-04 13:10:50 +01:00
parent e1ece5b986
commit 023d8cf073

View File

@ -10,21 +10,55 @@ impl Law {
section: Vec::new(),
}
}
}
fn get_classifiers(&self) -> Vec<Classifier> {
let mut ret = Vec::new();
for sec in &self.section {
if let Some(header) = &sec.header {
for class in header.get_all_classifiers() {
ret.push(class);
}
}
}
ret
#[derive(Debug, PartialEq)]
struct LawBuilder {
name: String, //ABGB, UrhG
classifiers: Vec<Classifier>,
cur_classifier_index: Option<usize>,
}
impl LawBuilder {
fn new(name: &str) -> Self {
let mut classifiers = Vec::new();
if name == "UrhG" {
let hauptstueck = Classifier::new("Hauptstück");
classifiers.push(hauptstueck.clone());
let mut abschnitt = Classifier::new("Abschnitt");
abschnitt.set_parent(hauptstueck);
classifiers.push(abschnitt);
}
fn new_header(&self, name: &str) {
//TODO: continue here
Self {
name: name.into(),
classifiers,
cur_classifier_index: None,
}
}
fn new_header(&mut self, name: &str) {
let classifier_index = self
.classifiers
.iter()
.position(|class| class.contains(name));
match classifier_index {
Some(index) => {
self.classifiers[index].add_instance(ClassifierInstance::new(name));
self.cur_classifier_index = Some(index);
}
None => panic!("No classifier for {name}"),
}
}
fn new_par(&mut self, par: Content) {
if let Some(index) = self.cur_classifier_index {
self.classifiers[index].add_par(par);
} else {
panic!("Expected at least one classifier");
}
}
}
@ -34,6 +68,7 @@ struct Section {
header: Option<Header>,
}
#[derive(Clone)]
struct Header {
classifier: Classifier, // Hauptstück, Theil, Abschnitt, ol
name: String, // 1. Hauptstück, 3. Theil, 7. Abschnitt, li
@ -54,13 +89,103 @@ impl Header {
}
}
#[derive(Clone)]
struct Classifier {
name: String, // Hauptstück, Theil, Abschnitt, ol
#[derive(Clone, Debug, PartialEq)]
struct ClassifierInstance {
name: String,
content: Vec<Content>,
}
impl ClassifierInstance {
fn new(name: &str) -> Self {
Self {
name: name.into(),
content: Vec::new(),
}
}
fn add_par(&mut self, content: Content) {
self.content.push(content);
}
}
#[derive(Clone, Debug, PartialEq)]
struct Classifier {
name: String, // Hauptstück, Theil, Abschnitt, ol
parent: Option<Box<Classifier>>,
instances: Vec<ClassifierInstance>,
}
impl Classifier {
fn new(name: &str) -> Self {
Self {
name: name.into(),
parent: None,
instances: Vec::new(),
}
}
fn set_parent(&mut self, parent: Classifier) {
self.parent = Some(Box::new(parent));
}
fn contains(&self, name: &str) -> bool {
name.contains(&self.name)
}
fn add_instance(&mut self, name: ClassifierInstance) {
self.instances.push(name);
}
fn add_par(&mut self, content: Content) {
self.instances.last_mut().unwrap().add_par(content);
}
}
#[derive(Clone, Debug, PartialEq)]
enum Content {
Text(String), //This is my direct law text
Item((String, Box<Content>)), //(1) This is general law. (2) This is more specific law
List(Vec<Box<Content>>), //1. my first item
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test() {
let mut builder = LawBuilder::new("UrhG");
builder.new_header("1. Hauptstück");
builder.new_header("2. Abschnitt");
builder.new_par(Content::Text("Mein erster Paragraph".into()));
let expected = LawBuilder {
name: "UrhG".into(),
classifiers: vec![
Classifier {
name: "Hauptstück".into(),
parent: None,
instances: vec![ClassifierInstance {
name: "1. Hauptstück".into(),
content: vec![],
}],
},
Classifier {
name: "Abschnitt".into(),
parent: Some(Box::new(Classifier {
name: "Hauptstück".into(),
parent: None,
instances: vec![],
})),
instances: vec![ClassifierInstance {
name: "2. Abschnitt".into(),
content: vec![Content::Text("Mein erster Paragraph".into())],
}],
},
],
cur_classifier_index: Some(1),
};
assert_eq!(builder, expected);
}
}