pub mod encoding;
pub mod meta;
pub mod place;
pub mod source;
use super::UserDefinedTag;
use crate::{
parser::{parse_subset, Parser},
tokenizer::Tokenizer,
types::{
date::Date,
header::{encoding::Encoding, meta::GedcomMeta, place::HeadPlac, source::HeadSour},
note::Note,
},
};
#[cfg(feature = "json")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Default)]
#[cfg_attr(feature = "json", derive(Serialize, Deserialize))]
pub struct Header {
pub gedcom: Option<GedcomMeta>,
pub encoding: Option<Encoding>,
pub source: Option<HeadSour>,
pub destination: Option<String>,
pub date: Option<Date>,
pub submitter_tag: Option<String>,
pub submission_tag: Option<String>,
pub copyright: Option<String>,
pub language: Option<String>,
pub filename: Option<String>,
pub note: Option<Note>,
pub place: Option<HeadPlac>,
pub custom_data: Vec<Box<UserDefinedTag>>,
}
impl Header {
#[must_use]
pub fn new(tokenizer: &mut Tokenizer, level: u8) -> Header {
let mut header = Header::default();
header.parse(tokenizer, level);
header
}
}
impl Parser for Header {
fn parse(&mut self, tokenizer: &mut Tokenizer, level: u8) {
tokenizer.next_token();
let handle_subset = |tag: &str, tokenizer: &mut Tokenizer| match tag {
"GEDC" => self.gedcom = Some(GedcomMeta::new(tokenizer, level + 1)),
"SOUR" => self.source = Some(HeadSour::new(tokenizer, level + 1)),
"DEST" => self.destination = Some(tokenizer.take_line_value()),
"DATE" => self.date = Some(Date::new(tokenizer, level + 1)),
"SUBM" => self.submitter_tag = Some(tokenizer.take_line_value()),
"SUBN" => self.submission_tag = Some(tokenizer.take_line_value()),
"FILE" => self.filename = Some(tokenizer.take_line_value()),
"COPR" => self.copyright = Some(tokenizer.take_continued_text(level + 1)),
"CHAR" => self.encoding = Some(Encoding::new(tokenizer, level + 1)),
"LANG" => self.language = Some(tokenizer.take_line_value()),
"NOTE" => self.note = Some(Note::new(tokenizer, level + 1)),
"PLAC" => self.place = Some(HeadPlac::new(tokenizer, level + 1)),
_ => panic!("{} Unhandled Header Tag: {}", tokenizer.debug(), tag),
};
self.custom_data = parse_subset(tokenizer, level, handle_subset);
}
}
#[cfg(test)]
mod tests {
use crate::Gedcom;
#[test]
fn test_parse_header_record() {
let sample = "\
0 HEAD\n\
1 GEDC\n\
2 VERS 5.5\n\
1 DEST Destination of transmission\n\
1 SUBM @SUBMITTER@\n\
1 SUBN @SUBMISSION@\n\
1 FILE ALLGED.GED\n\
1 LANG language\n\
0 TRLR";
let mut doc = Gedcom::new(sample.chars());
let data = doc.parse();
let header = data.header.unwrap();
let dest = header.destination.unwrap();
assert_eq!(dest, "Destination of transmission");
let submitter = header.submitter_tag.unwrap();
assert_eq!(submitter, "@SUBMITTER@");
let submission = header.submission_tag.unwrap();
assert_eq!(submission, "@SUBMISSION@");
let lang = header.language.unwrap();
assert_eq!(lang.as_str(), "language");
let file = header.filename.unwrap();
assert_eq!(file, "ALLGED.GED");
}
}