push
This commit is contained in:
parent
023d8cf073
commit
58dd701c95
55
src/law.rs
55
src/law.rs
@ -1,10 +1,12 @@
|
|||||||
struct Law {
|
use crate::overview;
|
||||||
|
|
||||||
|
pub(crate) struct Law {
|
||||||
name: String, //ABGB, UrhG
|
name: String, //ABGB, UrhG
|
||||||
section: Vec<Section>, // § 1, § 2, ...
|
section: Vec<Section>, // § 1, § 2, ...
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Law {
|
impl Law {
|
||||||
fn new(name: &str) -> Self {
|
pub(crate) fn new(name: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
section: Vec::new(),
|
section: Vec::new(),
|
||||||
@ -13,17 +15,20 @@ impl Law {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
struct LawBuilder {
|
pub(crate) struct LawBuilder {
|
||||||
name: String, //ABGB, UrhG
|
name: String, //ABGB, UrhG
|
||||||
classifiers: Vec<Classifier>,
|
classifiers: Vec<Classifier>,
|
||||||
cur_classifier_index: Option<usize>,
|
cur_classifier_index: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LawBuilder {
|
impl LawBuilder {
|
||||||
fn new(name: &str) -> Self {
|
pub(crate) fn new(name: &str) {
|
||||||
|
//TODO: return Law (not LawBuilder)
|
||||||
let mut classifiers = Vec::new();
|
let mut classifiers = Vec::new();
|
||||||
|
|
||||||
|
let mut law_id = None;
|
||||||
if name == "UrhG" {
|
if name == "UrhG" {
|
||||||
|
law_id = Some(10001848);
|
||||||
let hauptstueck = Classifier::new("Hauptstück");
|
let hauptstueck = Classifier::new("Hauptstück");
|
||||||
classifiers.push(hauptstueck.clone());
|
classifiers.push(hauptstueck.clone());
|
||||||
|
|
||||||
@ -32,14 +37,16 @@ impl LawBuilder {
|
|||||||
classifiers.push(abschnitt);
|
classifiers.push(abschnitt);
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
let mut builder = Self {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
classifiers,
|
classifiers,
|
||||||
cur_classifier_index: None,
|
cur_classifier_index: None,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
overview::parse(law_id.unwrap(), &mut builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_header(&mut self, name: &str) {
|
pub(crate) fn new_header(&mut self, name: &str) {
|
||||||
let classifier_index = self
|
let classifier_index = self
|
||||||
.classifiers
|
.classifiers
|
||||||
.iter()
|
.iter()
|
||||||
@ -53,7 +60,13 @@ impl LawBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_par(&mut self, par: Content) {
|
pub(crate) fn new_desc(&mut self, desc: &str) {
|
||||||
|
if let Some(index) = self.cur_classifier_index {
|
||||||
|
self.classifiers[index].set_desc(desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn new_par(&mut self, par: Content) {
|
||||||
if let Some(index) = self.cur_classifier_index {
|
if let Some(index) = self.cur_classifier_index {
|
||||||
self.classifiers[index].add_par(par);
|
self.classifiers[index].add_par(par);
|
||||||
} else {
|
} else {
|
||||||
@ -62,14 +75,14 @@ impl LawBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Section {
|
pub(crate) struct Section {
|
||||||
symb: String, // §"1", §"2", ...
|
symb: String, // §"1", §"2", ...
|
||||||
content: Content,
|
content: Content,
|
||||||
header: Option<Header>,
|
header: Option<Header>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Header {
|
pub(crate) 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
|
||||||
parent: Option<Box<Header>>,
|
parent: Option<Box<Header>>,
|
||||||
@ -90,8 +103,9 @@ impl Header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
struct ClassifierInstance {
|
pub(crate) struct ClassifierInstance {
|
||||||
name: String,
|
name: String,
|
||||||
|
desc: Option<String>,
|
||||||
content: Vec<Content>,
|
content: Vec<Content>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,16 +113,22 @@ impl ClassifierInstance {
|
|||||||
fn new(name: &str) -> Self {
|
fn new(name: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
|
desc: None,
|
||||||
content: Vec::new(),
|
content: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_desc(&mut self, desc: &str) {
|
||||||
|
self.desc = Some(desc.into());
|
||||||
|
}
|
||||||
|
|
||||||
fn add_par(&mut self, content: Content) {
|
fn add_par(&mut self, content: Content) {
|
||||||
self.content.push(content);
|
self.content.push(content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
struct Classifier {
|
pub(crate) struct Classifier {
|
||||||
name: String, // Hauptstück, Theil, Abschnitt, ol
|
name: String, // Hauptstück, Theil, Abschnitt, ol
|
||||||
parent: Option<Box<Classifier>>,
|
parent: Option<Box<Classifier>>,
|
||||||
instances: Vec<ClassifierInstance>,
|
instances: Vec<ClassifierInstance>,
|
||||||
@ -138,10 +158,13 @@ impl Classifier {
|
|||||||
fn add_par(&mut self, content: Content) {
|
fn add_par(&mut self, content: Content) {
|
||||||
self.instances.last_mut().unwrap().add_par(content);
|
self.instances.last_mut().unwrap().add_par(content);
|
||||||
}
|
}
|
||||||
|
fn set_desc(&mut self, desc: &str) {
|
||||||
|
self.instances.last_mut().unwrap().set_desc(desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
enum Content {
|
pub(crate) 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
|
||||||
@ -155,8 +178,8 @@ mod tests {
|
|||||||
fn test() {
|
fn test() {
|
||||||
let mut builder = LawBuilder::new("UrhG");
|
let mut builder = LawBuilder::new("UrhG");
|
||||||
|
|
||||||
builder.new_header("1. Hauptstück");
|
builder.new_header("1. Hauptstück", None);
|
||||||
builder.new_header("2. Abschnitt");
|
builder.new_header("2. Abschnitt", None);
|
||||||
|
|
||||||
builder.new_par(Content::Text("Mein erster Paragraph".into()));
|
builder.new_par(Content::Text("Mein erster Paragraph".into()));
|
||||||
|
|
||||||
@ -168,6 +191,7 @@ mod tests {
|
|||||||
parent: None,
|
parent: None,
|
||||||
instances: vec![ClassifierInstance {
|
instances: vec![ClassifierInstance {
|
||||||
name: "1. Hauptstück".into(),
|
name: "1. Hauptstück".into(),
|
||||||
|
desc: None,
|
||||||
content: vec![],
|
content: vec![],
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
@ -180,6 +204,7 @@ mod tests {
|
|||||||
})),
|
})),
|
||||||
instances: vec![ClassifierInstance {
|
instances: vec![ClassifierInstance {
|
||||||
name: "2. Abschnitt".into(),
|
name: "2. Abschnitt".into(),
|
||||||
|
desc: None,
|
||||||
content: vec![Content::Text("Mein erster Paragraph".into())],
|
content: vec![Content::Text("Mein erster Paragraph".into())],
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
use law::LawBuilder;
|
||||||
|
|
||||||
mod law;
|
mod law;
|
||||||
mod overview;
|
mod overview;
|
||||||
mod par;
|
mod par;
|
||||||
@ -39,7 +41,6 @@ impl From<roxmltree::Error> for Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let mut law = LawBuilder::new("UrhG");
|
||||||
//overview::parse(10001899).unwrap(); //TEG
|
//overview::parse(10001899).unwrap(); //TEG
|
||||||
overview::parse(10001848).unwrap(); //UrhG
|
|
||||||
//par::parse("https://www.ris.bka.gv.at/Dokumente/Bundesnormen/NOR12025172/NOR12025172.xml");
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ mod parser;
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use time::{format_description, OffsetDateTime};
|
use time::{format_description, OffsetDateTime};
|
||||||
|
|
||||||
use crate::{overview::parser::OgdSearchResult, Error};
|
use crate::{law::LawBuilder, overview::parser::OgdSearchResult, Error};
|
||||||
|
|
||||||
/// Returns the current date in YYYY-MM-DD format. Needed for RIS API query to get current version of the overview.
|
/// Returns the current date in YYYY-MM-DD format. Needed for RIS API query to get current version of the overview.
|
||||||
fn current_date() -> String {
|
fn current_date() -> String {
|
||||||
@ -37,13 +37,14 @@ pub(crate) struct Wrapper {
|
|||||||
ogd_search_result: OgdSearchResult,
|
ogd_search_result: OgdSearchResult,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse(overview_id: usize) -> Result<(), Error> {
|
pub(crate) fn parse(overview_id: usize, builder: &mut LawBuilder) -> Result<(), Error> {
|
||||||
let json = fetch_page(overview_id)?;
|
let json = fetch_page(overview_id)?;
|
||||||
|
|
||||||
let wrapper: Wrapper = serde_json::from_str(&json)?;
|
let wrapper: Wrapper = serde_json::from_str(&json)?;
|
||||||
|
|
||||||
for par in wrapper.ogd_search_result.get_par() {
|
for par in wrapper.ogd_search_result.get_par().into_iter().skip(1) {
|
||||||
crate::par::parse(&par).unwrap();
|
crate::par::parse(&par, builder).unwrap();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
mod parser;
|
mod parser;
|
||||||
|
|
||||||
use crate::{par::parser::Risdok, Error};
|
use crate::{law::LawBuilder, par::parser::Risdok, Error};
|
||||||
|
|
||||||
fn fetch_page(url: &str) -> Result<String, Error> {
|
fn fetch_page(url: &str) -> Result<String, Error> {
|
||||||
Ok(ureq::get(url).call()?.into_string()?)
|
Ok(ureq::get(url).call()?.into_string()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn parse(url: &str) -> Result<(), Error> {
|
pub(crate) fn parse(url: &str, builder: &mut LawBuilder) -> Result<(), Error> {
|
||||||
println!("{url}");
|
println!("{url}");
|
||||||
let xml = fetch_page(url)?;
|
let xml = fetch_page(url)?;
|
||||||
let risdok = Risdok::from_str(&xml)?;
|
let risdok = Risdok::from_str(&xml, builder)?;
|
||||||
|
|
||||||
println!("{risdok}");
|
println!("{builder:#?}");
|
||||||
|
//println!("{risdok}");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use std::fmt::Display;
|
|||||||
|
|
||||||
use roxmltree::Node;
|
use roxmltree::Node;
|
||||||
|
|
||||||
use crate::Error;
|
use crate::{law::LawBuilder, Error};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub(crate) struct Risdok {
|
pub(crate) struct Risdok {
|
||||||
@ -12,14 +12,14 @@ pub(crate) struct Risdok {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Risdok {
|
impl Risdok {
|
||||||
pub(crate) fn parse(n: Node) -> Self {
|
pub(crate) fn parse(n: Node, builder: &mut LawBuilder) -> Self {
|
||||||
assert!(n.tag_name().name() == "risdok");
|
assert!(n.tag_name().name() == "risdok");
|
||||||
|
|
||||||
let mut c = n.children();
|
let mut c = n.children();
|
||||||
|
|
||||||
let ret = Self {
|
let ret = Self {
|
||||||
metadaten: Metadaten::parse(c.next().unwrap()),
|
metadaten: Metadaten::parse(c.next().unwrap()),
|
||||||
nutzdaten: Nutzdaten::parse(c.next().unwrap()),
|
nutzdaten: Nutzdaten::parse(c.next().unwrap(), builder),
|
||||||
layoutdaten: Layoutdaten::parse(c.next().unwrap()),
|
layoutdaten: Layoutdaten::parse(c.next().unwrap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -28,11 +28,11 @@ impl Risdok {
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_str(xml: &str) -> Result<Self, Error> {
|
pub(crate) fn from_str(xml: &str, builder: &mut LawBuilder) -> Result<Self, Error> {
|
||||||
let doc = roxmltree::Document::parse(&xml)?;
|
let doc = roxmltree::Document::parse(&xml)?;
|
||||||
let root = doc.root();
|
let root = doc.root();
|
||||||
assert_eq!(root.children().into_iter().count(), 1);
|
assert_eq!(root.children().into_iter().count(), 1);
|
||||||
Ok(Self::parse(root.children().next().unwrap()))
|
Ok(Self::parse(root.children().next().unwrap(), builder))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,12 +70,12 @@ pub(crate) struct Nutzdaten {
|
|||||||
abschnitt: Abschnitt,
|
abschnitt: Abschnitt,
|
||||||
}
|
}
|
||||||
impl Nutzdaten {
|
impl Nutzdaten {
|
||||||
pub(crate) fn parse(n: Node) -> Self {
|
pub(crate) fn parse(n: Node, builder: &mut LawBuilder) -> Self {
|
||||||
assert!(n.tag_name().name() == "nutzdaten");
|
assert!(n.tag_name().name() == "nutzdaten");
|
||||||
|
|
||||||
let mut c = n.children();
|
let mut c = n.children();
|
||||||
let ret = Self {
|
let ret = Self {
|
||||||
abschnitt: Abschnitt::parse(c.next().unwrap()),
|
abschnitt: Abschnitt::parse(c.next().unwrap(), builder),
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(c.next(), None);
|
assert_eq!(c.next(), None);
|
||||||
@ -86,12 +86,11 @@ impl Nutzdaten {
|
|||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub(crate) struct Abschnitt {
|
pub(crate) struct Abschnitt {
|
||||||
ueberschrifts: Vec<Ueberschrift>,
|
|
||||||
ueberschriftPara: Option<Ueberschrift>,
|
ueberschriftPara: Option<Ueberschrift>,
|
||||||
absatze: Vec<AbsatzAbs>,
|
absatze: Vec<AbsatzAbs>,
|
||||||
}
|
}
|
||||||
impl Abschnitt {
|
impl Abschnitt {
|
||||||
pub(crate) fn parse(n: Node) -> Self {
|
pub(crate) fn parse(n: Node, builder: &mut LawBuilder) -> Self {
|
||||||
assert!(n.tag_name().name() == "abschnitt");
|
assert!(n.tag_name().name() == "abschnitt");
|
||||||
|
|
||||||
let mut c = n.children().peekable();
|
let mut c = n.children().peekable();
|
||||||
@ -119,16 +118,18 @@ impl Abschnitt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut ueberschrifts = Vec::new();
|
|
||||||
loop {
|
loop {
|
||||||
match &c.peek() {
|
match c.peek() {
|
||||||
Some(child) => {
|
Some(child) => {
|
||||||
if Ueberschrift::test(&child, "g1") {
|
if Ueberschrift::test(&child, "g1") {
|
||||||
ueberschrifts.push(Ueberschrift::parse(c.next().unwrap(), "g1"));
|
let ueberschrift = Ueberschrift::parse(c.next().unwrap(), "g1");
|
||||||
|
builder.new_header(&ueberschrift.content);
|
||||||
} else if Ueberschrift::test(&child, "g2") {
|
} else if Ueberschrift::test(&child, "g2") {
|
||||||
ueberschrifts.push(Ueberschrift::parse(c.next().unwrap(), "g2"));
|
let ueberschrift = Ueberschrift::parse(c.next().unwrap(), "g2");
|
||||||
|
builder.new_desc(&ueberschrift.content);
|
||||||
} else if Ueberschrift::test(&child, "g1min") {
|
} else if Ueberschrift::test(&child, "g1min") {
|
||||||
ueberschrifts.push(Ueberschrift::parse(c.next().unwrap(), "g1min"));
|
let ueberschrift = Ueberschrift::parse(c.next().unwrap(), "g1min");
|
||||||
|
builder.new_header(&ueberschrift.content);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -181,7 +182,6 @@ impl Abschnitt {
|
|||||||
Self {
|
Self {
|
||||||
ueberschriftPara,
|
ueberschriftPara,
|
||||||
absatze,
|
absatze,
|
||||||
ueberschrifts,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user