gutenberg-rs 0.1.0

This crate is used to get information and data from gutenberg (https://www.gutenberg.org/)
Documentation
use crate::book::GutenbergFileEntry;
use crate::error::Error;
use crate::fst_parser::{FSTParser, ParseItemResult, ParseResult};
use crate::fst_parser_type::ParseType;

use std::str;

pub(crate) struct FSTParserFileNode {
    pos: i32,
    attribute_states_idx: i32,
    states: Vec<&'static str>,
    attribute: &'static str,
    has_node: bool,
    parse_type: ParseType,

    files: Vec<GutenbergFileEntry>,
}

impl FSTParser for FSTParserFileNode {
    fn text(
        &mut self,
        text: &str,
        parse_result: &mut ParseResult,
        book_id: i32,
    ) -> Result<(), Error> {
        if !self.is_found() {
            return Ok(());
        }
        self.has_node = true;
        let idx = parse_result.add_file_type(text.to_string(), book_id)?;
        if let Some(last_file) = self.files.last_mut() { 
            last_file.file_type_id = (idx + 1) as i32;
            return Ok(());
        }
        Err(Error::InvalidRdf("No files".to_string()))
    }

    fn reset(&mut self) {
        self.has_node = false;
        self.pos = -1;
        self.files.clear();
    }

    fn attribute(
        &mut self,
        attribute_name: &str,
        attribute_value: &str,
        parse_result: &mut ParseResult,
        book_id: i32,
    ) -> Result<(), Error> {
        if self.attribute_states_idx != self.pos {
            return Ok(());
        }

        if attribute_name != self.attribute {
            return Ok(());
        }
        
        let value = attribute_value;
        let file_link_id = parse_result.add_file(value.to_string(), book_id)?;
   
        self.files.push(GutenbergFileEntry {
            file_link_id: file_link_id as i32,
            file_type_id: -1,
        });
        Ok(())
    }

    fn start_node(&mut self, node_name: &str) {
        if self.pos == -1 && node_name.eq(self.states[0]) {
            self.pos = 0;
            return;
        }

        if self.pos != -1 {
            let check_index = self.pos + 1;
            if check_index >= self.states.len() as i32 {
                return;
            }
            if node_name.eq(self.states[check_index as usize]) {
                self.pos += 1;
            }
        }
    }

    fn end_node(&mut self, node_name: &str) {
        if self.pos > -1 {
            if self.states[self.pos as usize].eq(node_name) {
                self.pos -= 1;
            }
        }
    }

    fn is_found(&self) -> bool {
        self.pos == self.states.len() as i32 - 1
    }

    fn has_results(&self) -> bool {
        return self.has_node && !self.files.is_empty();
    }

    fn get_parse_type(&self) -> ParseType {
        self.parse_type
    }

    fn get_result(&self) -> Result<&ParseItemResult, Error> {
        Err(Error::InvalidResult("no result in file parser".to_string()))
    }

    fn get_files(&self) -> Result<Vec<GutenbergFileEntry>, Error> {
        Ok(self.files.to_vec())
    }
}

impl FSTParserFileNode {
    pub fn build(
        states: Vec<&'static str>,
        attribute: &'static str,
        parse_type: ParseType,
    ) -> Box<dyn FSTParser> {
        Box::new(FSTParserFileNode {
            pos: -1,
            states,
            has_node: false,
            parse_type,
            attribute,
            attribute_states_idx: 1,
            files: Vec::new(),
        })
    }
}