gedcom_rs/types/
source.rs1use super::{corporation::Corporation, Line, SourceData};
5
6#[derive(Debug, Default)]
30pub struct Source {
31 pub corporation: Option<Corporation>,
33 pub name: Option<String>,
35 pub source: String,
36 pub data: Option<SourceData>,
37 pub version: Option<String>,
39}
40
41impl Source {
42 pub fn parse(mut buffer: &str) -> (&str, Option<Source>) {
44 let mut source = Source {
45 corporation: None,
46 data: None,
47 name: None,
48 source: "".to_string(),
49 version: None,
50 };
51 let mut line: Line;
52
53 line = Line::peek(&mut buffer).unwrap();
54
55 if line.level == 1 && line.tag == "SOUR" {
57 line = Line::parse(&mut buffer).unwrap();
59
60 source.source = line.value.to_string();
61
62 let mut next = Line::peek(&mut buffer).unwrap();
63
64 while next.level >= line.level {
65 let inner_line: Line = Line::peek(&mut buffer).unwrap();
68
69 match inner_line.tag {
71 "_TREE" => {
73 println!("Skipping _TREE");
78 Line::parse(&mut buffer).unwrap();
80 }
81 "CORP" => {
82 (buffer, source.corporation) = Corporation::parse(buffer);
83 }
84 "NAME" => {
85 source.name = Some(inner_line.value.to_string());
86 Line::parse(&mut buffer).unwrap();
87 }
88 "VERS" => {
89 source.version = Some(inner_line.value.to_string());
90 Line::parse(&mut buffer).unwrap();
91 }
92 "DATA" => {
93 (buffer, source.data) = SourceData::parse(buffer);
94 }
95 _ => {
96 println!("Unknown line: {:?}", inner_line);
97
98 Line::parse(&mut buffer).unwrap();
100 }
101 }
102
103 if !buffer.is_empty() {
105 next = Line::peek(&mut buffer).unwrap();
106 if next.level <= 1 {
107 break;
108 }
109 } else {
110 break;
111 }
112 }
113 }
114
115 (buffer, Some(source))
116 }
117}
118
119#[cfg(test)]
120mod tests {
121 use crate::types::DateTime;
122
123 use super::{Source, SourceData};
124
125 #[test]
126 fn parse() {
127 let data = vec![
128 "1 SOUR GEDitCOM",
129 "2 VERS 2.9.4",
130 "2 NAME GEDitCOM",
131 "2 CORP RSAC Software",
132 "3 ADDR",
133 "4 ADR1 RSAC Software",
134 "4 ADR2 7108 South Pine Cone Street",
135 "4 ADR3 Ste 1",
136 "4 CITY Salt Lake City",
137 "4 STAE UT",
138 "4 POST 84121",
139 "4 CTRY USA",
140 "3 PHON +1-801-942-7768",
141 "3 PHON +1-801-555-1212",
142 "3 PHON +1-801-942-1148",
143 "3 EMAIL a@@example.com",
144 "3 EMAIL b@@example.com",
145 "3 EMAIL c@@example.com",
146 "3 FAX +1-801-942-7768",
147 "3 FAX +1-801-555-1212",
148 "3 FAX +1-801-942-1148",
149 "3 WWW https://www.example.com",
150 "3 WWW https://www.example.org",
151 "3 WWW https://www.example.net",
152 "2 DATA Name of source data",
153 "3 DATE 1 JAN 1998",
154 "3 COPR Copyright of source data",
155 ];
156
157 let (_data, source) = Source::parse(&data.join("\n"));
158 let sour = source.unwrap();
159
160 assert_eq!(sour.source, "GEDitCOM".to_string());
161 assert_eq!(sour.name, Some("GEDitCOM".to_string()));
162 assert_eq!(sour.version, Some("2.9.4".to_string()));
163 assert_eq!(
164 sour.data,
165 Some(SourceData {
166 name: Some("Name of source data".to_string()),
167 date: Some(DateTime {
168 date: Some("1 JAN 1998".to_string()),
169 time: None
170 }),
171 copyright: Some("Copyright of source data".to_string()),
172 })
173 );
174 let corp = sour.corporation.unwrap();
175
176 assert_eq!(corp.name, Some("RSAC Software".to_string()));
177
178 let corp_address: crate::types::Address = corp.address.unwrap();
179 assert_eq!(corp_address.addr1, Some("RSAC Software".to_string()));
180 assert_eq!(
181 corp_address.addr2,
182 Some("7108 South Pine Cone Street".to_string())
183 );
184 assert_eq!(corp_address.addr3, Some("Ste 1".to_string()));
185 assert_eq!(corp_address.city, Some("Salt Lake City".to_string()));
186 assert_eq!(corp_address.state, Some("UT".to_string()));
187 assert_eq!(corp_address.postal_code, Some("84121".to_string()));
188 assert_eq!(corp_address.country, Some("USA".to_string()));
189
190 assert!(corp_address.phone.contains(&"+1-801-942-7768".to_string()));
191 assert!(corp_address.phone.contains(&"+1-801-555-1212".to_string()));
192 assert!(corp_address.phone.contains(&"+1-801-942-1148".to_string()));
193 assert!(corp_address.email.contains(&"a@@example.com".to_string()));
194 assert!(corp_address.email.contains(&"b@@example.com".to_string()));
195 assert!(corp_address.email.contains(&"c@@example.com".to_string()));
196 assert!(corp_address.fax.contains(&"+1-801-942-1148".to_string()));
197 assert!(corp_address.fax.contains(&"+1-801-942-1148".to_string()));
198 assert!(corp_address.fax.contains(&"+1-801-942-1148".to_string()));
199 assert!(corp_address
200 .www
201 .contains(&"https://www.example.com".to_string()));
202 assert!(corp_address
203 .www
204 .contains(&"https://www.example.org".to_string()));
205 assert!(corp_address
206 .www
207 .contains(&"https://www.example.net".to_string()));
208 }
209}