1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use std::fmt;

use crate::fields::*;

/// A `VCard` holds the new line delimited raw `String` which represents a `VCard`
#[derive(Debug, PartialEq)]
pub struct VCard<'a> {
    pub raw: &'a str,
    pub full_name: FN<'a>,
    pub email_addr: Vec<EMail<'a>>,
}

impl<'a> VCard<'a> {
    pub fn new(raw: &'a str) -> VCard<'a> {
        let mut full_name: FN = FN::new("FN:UNKNOWN");
        let mut email_addr: Vec<EMail> = vec![];

        for line in raw.lines() {
            let lower = line.to_lowercase();
            if lower.starts_with("fn") {
                full_name = FN::new(line);
                continue;
            }
            if lower.starts_with("email") {
                email_addr.push(EMail::new(line));
            }
        }

        VCard {
            raw,
            full_name,
            email_addr,
        }
    }
}

impl<'a> fmt::Display for VCard<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if !self.email_addr.is_empty() {
            if self.email_addr.len() > 1 {
                let mut v: Vec<String> = vec![];
                for addr in &self.email_addr {
                    v.push(
                        vec![
                            addr.addr,
                            self.full_name.name,
                            &format!("{:?}", addr.r#type),
                        ]
                        .join("\t"),
                    )
                }
                write!(f, "{}", v.join("\n"))
            } else {
                write!(
                    f,
                    "{}\t{}\t{:?}",
                    self.email_addr[0], self.full_name, self.email_addr[0].r#type
                )
            }
        } else {
            write!(f, "{}", self.full_name)
        }
    }
}