pub mod file;
pub mod format;
pub mod link;
pub mod user;
use crate::{
parser::{parse_subset, Parser},
tokenizer::Tokenizer,
types::{
date::change_date::ChangeDate,
multimedia::{file::Reference, format::Format, user::UserReferenceNumber},
note::Note,
source::citation::Citation,
Xref,
},
};
#[cfg(feature = "json")]
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "json", derive(Serialize, Deserialize, PartialEq))]
pub struct Multimedia {
pub xref: Option<Xref>,
pub file: Option<Reference>,
pub form: Option<Format>,
pub title: Option<String>,
pub user_reference_number: Option<UserReferenceNumber>,
pub automated_record_id: Option<String>,
pub source_citation: Option<Citation>,
pub change_date: Option<ChangeDate>,
pub note_structure: Option<Note>,
}
impl Multimedia {
#[must_use]
fn with_xref(xref: Option<Xref>) -> Self {
Self {
xref,
..Default::default()
}
}
#[must_use]
pub fn new(tokenizer: &mut Tokenizer, level: u8, xref: Option<Xref>) -> Multimedia {
let mut obje = Multimedia::with_xref(xref);
obje.parse(tokenizer, level);
obje
}
}
impl Parser for Multimedia {
fn parse(&mut self, tokenizer: &mut Tokenizer, level: u8) {
tokenizer.next_token();
let handle_subset = |tag: &str, tokenizer: &mut Tokenizer| match tag {
"FILE" => self.file = Some(Reference::new(tokenizer, level + 1)),
"FORM" => self.form = Some(Format::new(tokenizer, level + 1)),
"TITL" => self.title = Some(tokenizer.take_line_value()),
"REFN" => {
self.user_reference_number = Some(UserReferenceNumber::new(tokenizer, level + 1));
}
"RIN" => self.automated_record_id = Some(tokenizer.take_line_value()),
"NOTE" => self.note_structure = Some(Note::new(tokenizer, level + 1)),
"SOUR" => self.source_citation = Some(Citation::new(tokenizer, level + 1)),
"CHAN" => self.change_date = Some(ChangeDate::new(tokenizer, level + 1)),
_ => panic!("{} Unhandled Multimedia Tag: {}", tokenizer.debug(), tag),
};
parse_subset(tokenizer, level, handle_subset);
}
}
#[cfg(test)]
mod tests {
use crate::Gedcom;
#[test]
fn test_parse_multimedia_record() {
let sample = "\
0 HEAD\n\
1 GEDC\n\
2 VERS 5.5\n\
2 FORM LINEAGE-LINKED\n\
0 @MEDIA1@ OBJE\n\
1 FILE /home/user/media/file_name.bmp\n\
1 TITL A Title\n\
1 RIN Automated Id\n\
0 TRLR";
let mut doc = Gedcom::new(sample.chars());
let data = doc.parse();
assert_eq!(data.multimedia.len(), 1);
let obje = &data.multimedia[0];
let xref = obje.xref.as_ref().unwrap();
assert_eq!(xref, "@MEDIA1@");
let titl = obje.title.as_ref().unwrap();
assert_eq!(titl, "A Title");
let rin = obje.automated_record_id.as_ref().unwrap();
assert_eq!(rin, "Automated Id");
}
#[test]
fn test_parse_multimedia_link() {
let sample = "\
0 HEAD\n\
1 CHAR UTF-8\n\
1 SOUR Ancestry.com Family Trees\n\
2 VERS (2010.3)\n\
2 NAME Ancestry.com Family Trees\n\
2 CORP Ancestry.com\n\
1 GEDC\n\
2 VERS 5.5\n\
2 FORM LINEAGE-LINKED\n\
0 OBJE\n\
1 FILE http://trees.ancestry.com/rd?f=image&guid=Xxxxxxxx-Xxxx-Xxxx-Xxxx-Xxxxxxxxxxxx&tid=Xxxxxxxx&pid=1\n\
1 FORM jpg\n\
1 TITL In Prague\n\
0 TRLR";
let mut record = Gedcom::new(sample.chars());
let data = record.parse();
assert_eq!(data.multimedia.len(), 1);
let obje = &data.multimedia[0];
assert_eq!(obje.title.as_ref().unwrap(), "In Prague");
let form = obje.form.as_ref().unwrap();
assert_eq!(form.value.as_ref().unwrap(), "jpg");
let file = obje.file.as_ref().unwrap();
assert_eq!(file.value.as_ref().unwrap(), "http://trees.ancestry.com/rd?f=image&guid=Xxxxxxxx-Xxxx-Xxxx-Xxxx-Xxxxxxxxxxxx&tid=Xxxxxxxx&pid=1");
}
#[test]
fn test_parse_multimedia_file_ref_record() {
let sample = "\
0 HEAD\n\
1 GEDC\n\
2 VERS 5.5\n\
0 @MEDIA1@ OBJE\n\
1 FILE /home/user/media/file_name.bmp\n\
2 FORM bmp\n\
3 TYPE photo
2 TITL A Bitmap\n\
0 TRLR";
let mut doc = Gedcom::new(sample.chars());
let data = doc.parse();
assert_eq!(data.multimedia.len(), 1);
let file = data.multimedia[0].file.as_ref().unwrap();
assert_eq!(
file.value.as_ref().unwrap(),
"/home/user/media/file_name.bmp"
);
assert_eq!(file.title.as_ref().unwrap(), "A Bitmap");
let form = file.form.as_ref().unwrap();
assert_eq!(form.value.as_ref().unwrap(), "bmp");
assert_eq!(form.source_media_type.as_ref().unwrap(), "photo");
}
#[test]
fn test_parse_multimedia_format_record() {
let sample = "\
0 HEAD\n\
1 GEDC\n\
2 VERS 5.5\n\
0 @MEDIA1@ OBJE\n\
1 FILE /home/user/media/file_name.bmp\n\
2 FORM bmp\n\
3 TYPE photo
0 TRLR";
let mut doc = Gedcom::new(sample.chars());
let data = doc.parse();
assert_eq!(data.multimedia.len(), 1);
let file = data.multimedia[0].file.as_ref().unwrap();
let form = file.form.as_ref().unwrap();
assert_eq!(form.value.as_ref().unwrap(), "bmp");
assert_eq!(form.source_media_type.as_ref().unwrap(), "photo");
}
#[test]
fn test_parse_user_reference_number_record() {
let sample = "\
0 HEAD\n\
1 GEDC\n\
2 VERS 5.5\n\
2 FORM LINEAGE-LINKED\n\
0 @MEDIA1@ OBJE\n\
1 FILE /home/user/media/file_name.bmp\n\
1 REFN 000\n\
2 TYPE User Reference Type\n\
0 TRLR";
let mut doc = Gedcom::new(sample.chars());
let data = doc.parse();
assert_eq!(data.multimedia.len(), 1);
let user_ref = data.multimedia[0].user_reference_number.as_ref().unwrap();
assert_eq!(user_ref.value.as_ref().unwrap(), "000");
assert_eq!(
user_ref.user_reference_type.as_ref().unwrap(),
"User Reference Type"
);
}
}