gutenberg_rs/
fst_parser.rs

1use crate::book::{Book, GutenbergFileEntry};
2use crate::error::Error;
3use crate::fst_parser_type::ParseType;
4use indexmap::IndexMap;
5
6#[derive(Default)]
7pub struct ParseItemResult {
8    pub item_links: Vec<usize>,
9}
10
11impl ParseItemResult {
12    pub fn add(
13        &mut self,
14        parse_result: &mut ParseResult,
15        parse_type: ParseType,
16        data: String,
17        book_id: i32,
18    ) -> Result<(), Error> {
19        let data_idx = parse_result.add_field(parse_type, data, book_id)?;
20        self.item_links.push(data_idx);
21        Ok(())
22    }
23
24    pub fn reset(&mut self) {
25        self.item_links.clear();
26    }
27}
28
29#[derive(Default)]
30pub struct DictionaryItemContent {
31    pub book_links: Vec<usize>,
32}
33
34#[derive(Default)]
35pub struct ParseResult {
36    pub books: Vec<Book>,
37    pub field_dictionaries: Vec<IndexMap<String, DictionaryItemContent>>,
38    pub files_dictionary: IndexMap<String, DictionaryItemContent>,
39    pub file_types_dictionary: IndexMap<String, DictionaryItemContent>,
40}
41
42impl ParseResult {
43    pub fn add(
44        map: &mut IndexMap<String, DictionaryItemContent>,
45        data: String,
46        book_id: i32,
47    ) -> Result<usize, Error> {
48        let map_entry = map.get_full_mut(data.as_str());
49        if map_entry.is_none() {
50            let result = map.insert_full(
51                data,
52                DictionaryItemContent {
53                    book_links: vec![book_id as usize],
54                },
55            );
56            return Ok(result.0);
57        }
58        match map_entry {
59            Some(data) => {
60                data.2.book_links.push(book_id as usize);
61                return Ok(data.0);
62            }
63            None => {
64                return Err(Error::InvalidRdf("Book links".to_string()));
65            }
66        }
67    }
68
69    pub fn add_file(&mut self, data: String, book_id: i32) -> Result<usize, Error> {
70        ParseResult::add(&mut self.files_dictionary, data, book_id)
71    }
72
73    pub fn add_file_type(&mut self, data: String, book_id: i32) -> Result<usize, Error> {
74        ParseResult::add(&mut self.file_types_dictionary, data, book_id)
75    }
76
77    pub fn add_field(
78        &mut self,
79        field: ParseType,
80        data: String,
81        book_id: i32,
82    ) -> Result<usize, Error> {
83        ParseResult::add(&mut self.field_dictionaries[field as usize], data, book_id)
84    }
85}
86pub trait FSTParser {
87    fn text(
88        &mut self,
89        text: &str,
90        parse_result: &mut ParseResult,
91        book_id: i32,
92    ) -> Result<(), Error>;
93    fn reset(&mut self);
94    fn start_node(&mut self, text: &str);
95    fn attribute(
96        &mut self,
97        attribute_name: &str,
98        attribute_value: &str,
99        parse_result: &mut ParseResult,
100        book_id: i32,
101    ) -> Result<(), Error>;
102    fn end_node(&mut self, node_name: &str);
103    fn is_found(&self) -> bool;
104    fn has_results(&self) -> bool;
105    fn get_parse_type(&self) -> ParseType;
106    fn get_result(&self) -> Result<&ParseItemResult, Error>;
107    fn get_files(&self) -> Result<Vec<GutenbergFileEntry>, Error>;
108}