Module parser

Source
Expand description

Parsing module which contains the API for mapping a NBF string to structs in rust.

Parsing a NBF string or text consists of the following steps:

  1. mapping the NBF blocks into nested instances of the DataTreeNode struct; and
  2. parsing the contents of the resulting tree of DataTreeNodes by implementing the trait FromTreeNode for the user-defined types to which the NBF text is supposed to be mapped.

§Examples

Parsing the simple structure from above can be achieved in the following way. (At the moment the API is too complicated to use. It will be simplified and support for serde is planned.)

use nbf::parser::{
    FromTreeNode,
    DataTreeNode,
    EmptyExternalErrorType,
    parse_uniform,
    parse_value,
    ParsingError,
    ParsingErrorType,
};

struct Person {
    name: String,
    year_of_birth: u16,
}
     
impl FromTreeNode for Person {
 
    type ExternalErrorType = EmptyExternalErrorType;
         
    fn get_keyword() -> &'static str {
        "person"
    }
 
    fn from_tree_node_internal(
        node: DataTreeNode<'_>
    ) -> Result<Self, ParsingError<Self::ExternalErrorType>> {
 
        let name = node.get_header_value().to_owned();
        let mut year_of_birth_opt: Option<u16> = None;
           
        let node_source_line = node.get_source_line();
 
        for child_node in node.get_children() {
            match child_node.get_keyword() {
                "year of birth" => year_of_birth_opt = Some(
                    parse_value(
                        child_node.get_header_value(),
                        child_node.get_source_line(),
                    )?
                ),
                _ => return Err(
                    ParsingError::new(
                        child_node.get_source_line(),
                        ParsingErrorType::UnknownKeyword(
                            child_node.get_keyword().to_owned()
                        ),
                    )
                )
            }
        }
 
        let Some( year_of_birth ) = year_of_birth_opt else {
            return Err(
                ParsingError::new(
                    node_source_line,
                    ParsingErrorType::MissingChild( "year of birth".to_owned() )
                )
            );
        };
 
        Ok( Person {
            name,
            year_of_birth,
        } )
    }
}
 
let source =
r#"person: Albert Einstein {
    year of birth: 1879
}
person: Max Planck {
    year of birth: 1858
}"#;
 
let persons: Vec<Person> = match parse_uniform( source ) {
    Ok( vec ) => vec,
    Err( error ) => panic!( "{}", error ),
};
 
assert_eq!( persons.len(), 2 );

assert_eq!( persons[0].name, "Albert Einstein" );
assert_eq!( persons[0].year_of_birth, 1879 );

assert_eq!( persons[1].name, "Max Planck" );
assert_eq!( persons[1].year_of_birth, 1858 );

Re-exports§

pub use error::ParsingError;
pub use error::ParsingErrorType;

Modules§

error
Module containing the error definitions of the parser.

Structs§

DataTreeNode
Instances of this struct represent blocks which contain the keyword, header value, first source line and children of the block in NBF. They contain no parsed values, just text mapped into snippets in the DataTreeNodes.
EmptyExternalErrorType
LineGroup
Group of lines, aware of their first line’s offset in an original text. Line groups depend on the life time of the original text by reason of optimisation. This allows LineGroups to be created as slices of other LineGroups without ever having to copy any Strings.

Traits§

FromTreeNode
Trait which guides the mapping from a DataTreeNode into the implementing type Self.

Functions§

parse_uniform
Function for conveniently parsing a string, given that all first level blocks are of the same type.
parse_value
Wrapper function to safely parse a type implementing FromStr or produce a ParsingError.