1use std::borrow::Cow;
4use std::fmt::{Display, Formatter};
5use std::mem;
6
7#[derive(Debug, Clone, Eq, Hash, PartialEq)]
28pub struct PersonName<'a> {
29 prefix: Option<Cow<'a, str>>,
30 family: Option<Cow<'a, str>>,
31 middle: Option<Cow<'a, str>>,
32 given: Option<Cow<'a, str>>,
33 suffix: Option<Cow<'a, str>>,
34}
35
36#[derive(Debug, Clone)]
49pub struct PersonNameBuilder<'a> {
50 person_name: PersonName<'a>,
51}
52
53impl Display for PersonName<'_> {
54 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
55 let components = &[
56 &self.prefix,
57 &self.given,
58 &self.middle,
59 &self.family,
60 &self.suffix,
61 ];
62
63 let mut c_iter = components.iter().copied().flatten().peekable();
64
65 while let Some(component) = c_iter.next() {
66 if c_iter.peek().is_some() {
67 write!(f, "{component} ")?
68 } else {
69 write!(f, "{component}")?
70 }
71 }
72 Ok(())
73 }
74}
75
76impl<'a> PersonName<'a> {
77 pub fn prefix(&self) -> Option<&str> {
79 self.prefix.as_deref()
80 }
81 pub fn suffix(&self) -> Option<&str> {
83 self.suffix.as_deref()
84 }
85 pub fn family(&self) -> Option<&str> {
87 self.family.as_deref()
88 }
89 pub fn given(&self) -> Option<&str> {
91 self.given.as_deref()
92 }
93 pub fn middle(&self) -> Option<&str> {
95 self.middle.as_deref()
96 }
97 pub fn to_dicom_string(&self) -> String {
103 let mut name = String::new();
104
105 let components = &[
106 &self.family,
107 &self.given,
108 &self.middle,
109 &self.prefix,
110 &self.suffix,
111 ];
112
113 let mut it = components.iter().rev().peekable();
114 while it.next_if(|component| component.is_none()).is_some() {}
116
117 let mut it = it.rev().peekable();
118 while let Some(option) = it.next() {
119 if let Some(component) = option {
120 name.push_str(component);
121 }
122 if it.peek().is_some() {
123 name.push('^');
124 }
125 }
126
127 name
128 }
129
130 pub fn from_text(slice: &'a str) -> PersonName<'a> {
137 let mut parts = slice.trim().split('^');
138
139 macro_rules! get_component {
140 () => {
141 parts
142 .next()
143 .and_then(|s| if s.is_empty() { None } else { Some(s.into()) })
144 };
145 }
146
147 let family = get_component!();
148 let given = get_component!();
149 let middle = get_component!();
150 let prefix = get_component!();
151 let suffix = get_component!();
152
153 PersonName {
154 prefix,
155 given,
156 family,
157 middle,
158 suffix,
159 }
160 }
161
162 pub fn builder() -> PersonNameBuilder<'a> {
166 PersonNameBuilder::new()
167 }
168}
169
170impl<'a> PersonNameBuilder<'a> {
171 pub fn new() -> PersonNameBuilder<'a> {
172 PersonNameBuilder {
173 person_name: PersonName {
174 prefix: None,
175 family: None,
176 middle: None,
177 given: None,
178 suffix: None,
179 },
180 }
181 }
182
183 pub fn with_family(&mut self, family_name: impl Into<Cow<'a, str>>) -> &mut Self {
185 self.person_name.family = Some(family_name.into());
186 self
187 }
188
189 pub fn with_middle(&mut self, middle_name: impl Into<Cow<'a, str>>) -> &mut Self {
191 self.person_name.middle = Some(middle_name.into());
192 self
193 }
194
195 pub fn with_given(&mut self, given_name: impl Into<Cow<'a, str>>) -> &mut Self {
197 self.person_name.given = Some(given_name.into());
198 self
199 }
200
201 pub fn with_prefix(&mut self, name_prefix: impl Into<Cow<'a, str>>) -> &mut Self {
203 self.person_name.prefix = Some(name_prefix.into());
204 self
205 }
206
207 pub fn with_suffix(&mut self, name_suffix: impl Into<Cow<'a, str>>) -> &mut Self {
209 self.person_name.suffix = Some(name_suffix.into());
210 self
211 }
212
213 pub fn build(&mut self) -> PersonName<'a> {
218 mem::take(self).person_name
219 }
220}
221
222impl Default for PersonNameBuilder<'_> {
223 fn default() -> Self {
224 Self::new()
225 }
226}
227
228impl<'a> From<PersonNameBuilder<'a>> for PersonName<'a> {
229 fn from(mut builder: PersonNameBuilder<'a>) -> Self {
230 builder.build()
231 }
232}
233
234impl<'a> From<&mut PersonNameBuilder<'a>> for PersonName<'a> {
235 fn from(builder: &mut PersonNameBuilder<'a>) -> Self {
236 builder.build()
237 }
238}
239
240#[cfg(test)]
241mod tests {
242 use super::*;
243 #[test]
244 fn test_person_name_to_dicom_string() {
245 let p = PersonNameBuilder::new()
246 .with_given("John")
247 .with_family("Adams")
248 .build();
249 assert_eq!(p.to_dicom_string(), "Adams^John".to_string());
250
251 let p: PersonName = PersonNameBuilder::new().with_prefix("Rev.").into();
252 assert_eq!(p.to_dicom_string(), "^^^Rev.".to_string());
253
254 let p = PersonNameBuilder::new().with_suffix("B.A. M.Div.").build();
255 assert_eq!(p.to_dicom_string(), "^^^^B.A. M.Div.".to_string());
256 let p = PersonName {
257 prefix: Some("Rev.".into()),
258 given: Some("John".into()),
259 middle: Some("Robert".into()),
260 family: Some("Adams".into()),
261 suffix: Some("B.A. M.Div.".into()),
262 };
263 assert_eq!(
264 p.to_dicom_string(),
265 "Adams^John^Robert^Rev.^B.A. M.Div.".to_string()
266 );
267 let p = PersonName {
268 prefix: None,
269 given: Some("John".into()),
270 middle: Some("Robert".into()),
271 family: Some("Adams".into()),
272 suffix: Some("B.A. M.Div.".into()),
273 };
274 assert_eq!(
275 p.to_dicom_string(),
276 "Adams^John^Robert^^B.A. M.Div.".to_string()
277 );
278 let p = PersonName {
279 prefix: Some("Rev.".into()),
280 given: Some("John".into()),
281 middle: Some("Robert".into()),
282 family: Some("Adams".into()),
283 suffix: None,
284 };
285 assert_eq!(p.to_dicom_string(), "Adams^John^Robert^Rev.".to_string());
286 let p = PersonName {
287 prefix: None,
288 given: Some("John".into()),
289 middle: Some("Robert".into()),
290 family: Some("Adams".into()),
291 suffix: None,
292 };
293 assert_eq!(p.to_dicom_string(), "Adams^John^Robert".to_string());
294 let p = PersonName::builder().with_middle("Robert").build();
295 assert_eq!(p.to_dicom_string(), "^^Robert".to_string());
296 }
297 #[test]
298 fn test_person_name_to_string() {
299 let p = PersonName::builder()
300 .with_given("John")
301 .with_family("Adams")
302 .build();
303 assert_eq!(p.to_string(), "John Adams".to_string());
304
305 let p = PersonName::builder().with_prefix("Rev.").build();
306 assert_eq!(p.to_string(), "Rev.".to_string());
307
308 let p = PersonName::builder().with_suffix("B.A. M.Div.").build();
309 assert_eq!(p.to_string(), "B.A. M.Div.".to_string());
310 let p = PersonName {
311 prefix: Some("Rev.".into()),
312 given: Some("John".into()),
313 middle: Some("Robert".into()),
314 family: Some("Adams".into()),
315 suffix: Some("B.A. M.Div.".into()),
316 };
317 assert_eq!(
318 p.to_string(),
319 "Rev. John Robert Adams B.A. M.Div.".to_string()
320 );
321 let p = PersonName {
322 prefix: None,
323 given: Some("John".into()),
324 middle: Some("Robert".into()),
325 family: Some("Adams".into()),
326 suffix: Some("B.A. M.Div.".into()),
327 };
328 assert_eq!(p.to_string(), "John Robert Adams B.A. M.Div.".to_string());
329 let p = PersonName {
330 prefix: Some("Rev.".into()),
331 given: Some("John".into()),
332 middle: Some("Robert".into()),
333 family: Some("Adams".into()),
334 suffix: None,
335 };
336 assert_eq!(p.to_string(), "Rev. John Robert Adams".to_string());
337 let p = PersonName {
338 prefix: None,
339 given: Some("John".into()),
340 middle: Some("Robert".into()),
341 family: Some("Adams".into()),
342 suffix: None,
343 };
344 assert_eq!(p.to_string(), "John Robert Adams".to_string());
345 let p = PersonName::builder().with_middle("Robert").build();
346 assert_eq!(p.to_string(), "Robert".to_string());
347 }
348 #[test]
349 fn person_name_from_slice() {
350 assert_eq!(
351 PersonName::from_text("^^Robert"),
352 PersonName::builder().with_middle("Robert").build()
353 );
354 assert_eq!(
355 PersonName::from_text("^^^Rev."),
356 PersonName::builder().with_prefix("Rev.").build()
357 );
358 assert_eq!(
359 PersonName::from_text("^^^^B.A. M.Div."),
360 PersonName::builder().with_suffix("B.A. M.Div.").build()
361 );
362 assert_eq!(
363 PersonName::from_text("^^Robert"),
364 PersonName::builder().with_middle("Robert").build()
365 );
366 assert_eq!(
367 PersonName::from_text("^John"),
368 PersonName::builder().with_given("John").build()
369 );
370 assert_eq!(
371 PersonName::from_text("Adams"),
372 PersonName::builder().with_family("Adams").build()
373 );
374 assert_eq!(
375 PersonName::from_text("Adams^^^^B.A. M.Div."),
376 PersonName::builder()
377 .with_family("Adams")
378 .with_suffix("B.A. M.Div.")
379 .build()
380 );
381 assert_eq!(
382 PersonName::from_text("Adams^^Robert^^B.A. M.Div."),
383 PersonName {
384 prefix: None,
385 given: None,
386 middle: Some("Robert".into()),
387 family: Some("Adams".into()),
388 suffix: Some("B.A. M.Div.".into()),
389 }
390 );
391 assert_eq!(
392 PersonName::from_text("Adams^John^Robert^Rev.^B.A. M.Div."),
393 PersonName {
394 prefix: Some("Rev.".into()),
395 given: Some("John".into()),
396 middle: Some("Robert".into()),
397 family: Some("Adams".into()),
398 suffix: Some("B.A. M.Div.".into()),
399 }
400 );
401 assert_eq!(
402 PersonName::from_text("Adams^ "),
403 PersonName {
404 prefix: None,
405 given: None,
406 middle: None,
407 family: Some("Adams".into()),
408 suffix: None,
409 }
410 );
411 }
412}