use crate::{
tokenizer::{Token, Tokenizer, TokenizerTrait},
types::custom::UserDefinedTag,
GedcomError,
};
pub trait Parser {
fn parse(&mut self, tokenizer: &mut Tokenizer, level: u8) -> Result<(), GedcomError>;
}
pub trait StreamParser {
fn parse_stream<T: TokenizerTrait>(
&mut self,
tokenizer: &mut T,
level: u8,
) -> Result<(), GedcomError>;
}
#[inline]
pub fn parse_subset<F>(
tokenizer: &mut Tokenizer,
level: u8,
mut tag_handler: F,
) -> Result<Vec<Box<UserDefinedTag>>, GedcomError>
where
F: FnMut(&str, &mut Tokenizer) -> Result<(), GedcomError>,
{
let mut non_standard_dataset = Vec::new();
loop {
if let Token::Level(curl_level) = tokenizer.current_token {
if curl_level <= level {
break;
}
}
match &tokenizer.current_token {
Token::Tag(tag) => {
let tag_clone = tag.clone();
tag_handler(tag_clone.as_ref(), tokenizer)?;
}
Token::CustomTag(tag) => {
let tag_clone = tag.clone();
non_standard_dataset.push(Box::new(UserDefinedTag::new(
tokenizer,
level + 1,
&tag_clone,
)?));
}
Token::Level(_) => tokenizer.next_token()?,
Token::LineValue(_) => {
tokenizer.next_token()?;
}
Token::EOF => break,
_ => {
return Err(GedcomError::ParseError {
line: tokenizer.line,
message: format!("Unhandled Token: {:?}", tokenizer.current_token),
})
}
}
}
Ok(non_standard_dataset)
}
#[inline]
pub fn parse_subset_stream<T, F>(
tokenizer: &mut T,
level: u8,
mut tag_handler: F,
) -> Result<Vec<Box<UserDefinedTag>>, GedcomError>
where
T: TokenizerTrait,
F: FnMut(&str, &mut T) -> Result<(), GedcomError>,
{
let mut non_standard_dataset = Vec::new();
loop {
if let Token::Level(curl_level) = tokenizer.current_token() {
if *curl_level <= level {
break;
}
}
match tokenizer.current_token() {
Token::Tag(tag) => {
let tag_clone = tag.clone();
tag_handler(tag_clone.as_ref(), tokenizer)?;
}
Token::CustomTag(tag) => {
let tag_clone = tag.clone();
non_standard_dataset.push(Box::new(UserDefinedTag::new_from_tokenizer(
tokenizer,
level + 1,
&tag_clone,
)?));
}
Token::Level(_) => tokenizer.next_token()?,
Token::LineValue(_) => {
tokenizer.next_token()?;
}
Token::EOF => break,
_ => {
return Err(GedcomError::ParseError {
line: tokenizer.line(),
message: format!("Unhandled Token: {:?}", tokenizer.current_token()),
})
}
}
}
Ok(non_standard_dataset)
}