second draft of lawbuilder
This commit is contained in:
		
							
								
								
									
										153
									
								
								src/law.rs
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								src/law.rs
									
									
									
									
									
								
							| @@ -10,21 +10,55 @@ impl Law { | |||||||
|             section: Vec::new(), |             section: Vec::new(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|     fn get_classifiers(&self) -> Vec<Classifier> { | #[derive(Debug, PartialEq)] | ||||||
|         let mut ret = Vec::new(); | struct LawBuilder { | ||||||
|         for sec in &self.section { |     name: String, //ABGB, UrhG | ||||||
|             if let Some(header) = &sec.header { |     classifiers: Vec<Classifier>, | ||||||
|                 for class in header.get_all_classifiers() { |     cur_classifier_index: Option<usize>, | ||||||
|                     ret.push(class); | } | ||||||
|                 } |  | ||||||
|             } | 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); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         Self { | ||||||
|  |             name: name.into(), | ||||||
|  |             classifiers, | ||||||
|  |             cur_classifier_index: None, | ||||||
|         } |         } | ||||||
|         ret |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn new_header(&self, name: &str) { |     fn new_header(&mut self, name: &str) { | ||||||
|         //TODO: continue here |         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>, |     header: Option<Header>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[derive(Clone)] | ||||||
| struct Header { | struct Header { | ||||||
|     classifier: Classifier, // Hauptstück, Theil, Abschnitt, ol |     classifier: Classifier, // Hauptstück, Theil, Abschnitt, ol | ||||||
|     name: String,           // 1. Hauptstück, 3. Theil, 7. Abschnitt, li |     name: String,           // 1. Hauptstück, 3. Theil, 7. Abschnitt, li | ||||||
| @@ -54,13 +89,103 @@ impl Header { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| #[derive(Clone)] | #[derive(Clone, Debug, PartialEq)] | ||||||
| struct Classifier { | struct ClassifierInstance { | ||||||
|     name: String, // Hauptstück, Theil, Abschnitt, ol |     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 { | enum Content { | ||||||
|     Text(String),                 //This is my direct law text |     Text(String),                 //This is my direct law text | ||||||
|     Item((String, Box<Content>)), //(1) This is general law. (2) This is more specific law |     Item((String, Box<Content>)), //(1) This is general law. (2) This is more specific law | ||||||
|     List(Vec<Box<Content>>),      //1. my first item |     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); | ||||||
|  |     } | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user