gazetta_model_ext/
person.rs1use std::fmt;
18
19use crate::link::Link;
20use crate::yaml::{self, Yaml};
21
22#[derive(Debug, Clone)]
23pub struct Person {
24 pub name: String,
25 pub email: Option<String>,
26 pub photo: Option<String>,
27 pub key: Option<Key>,
28 pub nicknames: Vec<String>,
29 pub also: Vec<Link>,
30}
31
32#[derive(Debug, Clone)]
33pub struct Key {
34 pub url: String,
35 pub fingerprint: String,
36}
37
38impl Key {
39 pub fn from_yaml(key: Yaml) -> Result<Self, &'static str> {
40 match key {
41 Yaml::Hash(mut key) => Ok(Key {
42 url: match key.remove(&yaml::KEYS.url) {
43 Some(Yaml::String(url)) => url,
44 Some(..) => return Err("key url must be a string"),
45 None => return Err("key url missing"),
46 },
47 fingerprint: match key.remove(&yaml::KEYS.fingerprint) {
48 Some(Yaml::String(fprint)) => fprint,
49 Some(..) => return Err("key fingerprint must be a string"),
50 None => return Err("key fingerprint missing"),
51 },
52 }),
53 _ => Err("if specified, key must be a hash"),
54 }
55 }
56}
57
58impl fmt::Display for Person {
59 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60 write!(f, "{}", self.name)?;
61 if let Some(ref email) = self.email {
62 write!(f, " <{email}>")?;
63 }
64 Ok(())
65 }
66}
67
68impl Person {
69 pub fn from_yaml(person: Yaml) -> Result<Self, &'static str> {
70 Ok(match person {
71 Yaml::Hash(mut person) => Person {
72 name: match person.remove(&yaml::KEYS.name) {
73 Some(Yaml::String(name)) => name,
74 None => return Err("missing name"),
75 _ => return Err("name must be a string"),
76 },
77 photo: match person.remove(&yaml::KEYS.photo) {
78 Some(Yaml::String(photo)) => Some(photo),
79 None => None,
80 _ => return Err("if specified, photo must be a string"),
81 },
82 email: match person.remove(&yaml::KEYS.email) {
83 Some(Yaml::String(email)) => Some(email),
84 None => None,
85 _ => return Err("if specified, email must be a string"),
86 },
87 nicknames: match person.remove(&yaml::KEYS.nicknames) {
88 Some(Yaml::String(nick)) => vec![nick],
89 Some(Yaml::Array(nicks)) => nicks
90 .into_iter()
91 .map(|nick| match nick {
92 Yaml::String(nick) => Ok(nick),
93 _ => Err("nicknames must be strings"),
94 })
95 .collect::<Result<_, _>>()?,
96 Some(..) => return Err("invalid nicknames value"),
97 None => vec![],
98 },
99 also: person
100 .remove(&yaml::KEYS.also)
101 .map(Link::many_from_yaml)
102 .transpose()?
103 .unwrap_or_else(Vec::new),
104 key: person
105 .remove(&yaml::KEYS.key)
106 .map(Key::from_yaml)
107 .transpose()?,
108 },
109 Yaml::String(name) => Person {
110 name,
111 email: None,
112 key: None,
113 also: Vec::new(),
114 photo: None,
115 nicknames: Vec::new(),
116 },
117 _ => return Err("invalid person"),
118 })
119 }
120}