1#[derive(Debug, Eq, PartialEq)]
3pub struct User {
4 name: Option<String>,
5 email: Option<String>,
6}
7
8impl User {
9 #[inline]
11 #[must_use]
12 pub fn new(name: Option<&str>, email: Option<&str>) -> Self {
13 Self {
14 email: email.map(String::from),
15 name: name.map(String::from),
16 }
17 }
18
19 #[inline]
21 #[must_use]
22 pub fn name(&self) -> Option<&str> {
23 self.name.as_deref()
24 }
25
26 #[inline]
28 #[must_use]
29 pub fn email(&self) -> Option<&str> {
30 self.email.as_deref()
31 }
32
33 #[inline]
35 #[must_use]
36 pub const fn is_some(&self) -> bool {
37 self.name.is_some() || self.email.is_some()
38 }
39
40 #[inline]
42 #[must_use]
43 pub const fn is_none(&self) -> bool {
44 self.name.is_none() && self.email.is_none()
45 }
46}
47
48impl ToString for User {
49 #[inline]
54 fn to_string(&self) -> String {
55 if let Some(name) = self.name.as_ref() {
56 if let Some(email) = self.email.as_ref() {
57 format!("{name} <{email}>")
58 }
59 else {
60 String::from(name)
61 }
62 }
63 else if let Some(email) = self.email.as_ref() {
64 format!("<{email}>")
65 }
66 else {
67 String::new()
68 }
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use claim::assert_some_eq;
75 use rstest::rstest;
76
77 use super::*;
78
79 #[test]
80 fn name() {
81 let user = User::new(Some("name"), None);
82 assert_some_eq!(user.name(), "name");
83 }
84
85 #[test]
86 fn email() {
87 let user = User::new(None, Some("email"));
88 assert_some_eq!(user.email(), "email");
89 }
90
91 #[rstest]
92 #[case(Some("name"), None)]
93 #[case(None, Some("email"))]
94 #[case(Some("email"), Some("email"))]
95 fn is_some_none_when_some(#[case] name: Option<&str>, #[case] email: Option<&str>) {
96 let user = User::new(name, email);
97 assert!(user.is_some());
98 assert!(!user.is_none());
99 }
100
101 #[test]
102 fn is_some_none_when_none() {
103 let user = User::new(None, None);
104 assert!(!user.is_some());
105 assert!(user.is_none());
106 }
107
108 #[test]
109 fn to_string_with_none_name_and_none_email() {
110 let user = User::new(None, None);
111 assert_eq!(user.to_string(), "");
112 }
113
114 #[test]
115 fn to_string_with_none_name_and_some_email() {
116 let user = User::new(None, Some("me@example.com"));
117 assert_eq!(user.to_string(), "<me@example.com>");
118 }
119
120 #[test]
121 fn to_string_with_some_name_and_none_email() {
122 let user = User::new(Some("Tim Oram"), None);
123 assert_eq!(user.to_string(), "Tim Oram");
124 }
125
126 #[test]
127 fn to_string_with_some_name_and_some_email() {
128 let user = User::new(Some("Tim Oram"), Some("me@example.com"));
129 assert_eq!(user.to_string(), "Tim Oram <me@example.com>");
130 }
131}