#![allow(clippy::non_ascii_literal)]
use crate::UserLibError;
use std::cmp::Eq;
use std::convert::TryFrom;
use std::fmt::{self, Display};
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum Gecos {
Detail {
full_name: String,
room: String,
phone_work: String,
phone_home: String,
other: Option<Vec<String>>,
},
Simple {
comment: String,
},
}
impl Gecos {
#[must_use]
pub fn get_comment(&self) -> Option<&str> {
match &self {
Self::Simple { comment, .. } => Some(comment),
Self::Detail { .. } => None,
}
}
#[must_use]
pub fn get_full_name(&self) -> Option<&str> {
match &self {
Self::Simple { .. } => None,
Self::Detail { full_name, .. } => {
if full_name.is_empty() {
None
} else {
Some(full_name)
}
}
}
}
#[must_use]
pub fn get_room(&self) -> Option<&str> {
match &self {
Self::Simple { .. } => None,
Self::Detail { room, .. } => {
if room.is_empty() {
None
} else {
Some(room)
}
}
}
}
#[must_use]
pub fn get_phone_work(&self) -> Option<&str> {
match &self {
Self::Simple { .. } => None,
Self::Detail { phone_work, .. } => {
if phone_work.is_empty() {
None
} else {
Some(phone_work)
}
}
}
}
#[must_use]
pub fn get_phone_home(&self) -> Option<&str> {
match &self {
Self::Simple { .. } => None,
Self::Detail { phone_home, .. } => {
if phone_home.is_empty() {
None
} else {
Some(phone_home)
}
}
}
}
#[must_use]
pub const fn get_other(&self) -> Option<&Vec<String>> {
match self {
Self::Simple { .. } => None,
Self::Detail { other, .. } => match other {
None => None,
Some(comments) => Some(comments),
},
}
}
}
impl Display for Gecos {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match &self {
Self::Simple { comment } => write!(f, "{}", comment),
Self::Detail {
full_name,
room,
phone_work,
phone_home,
other,
} => write!(
f,
"{},{},{},{}{}",
full_name,
room,
phone_work,
phone_home,
match other {
None => "".to_string(),
Some(cont) => format!(",{}", cont.join(",")),
}
),
}
}
}
impl TryFrom<String> for Gecos {
type Error = UserLibError;
fn try_from(source: String) -> std::result::Result<Self, Self::Error> {
let vals: Vec<String> = source.split(',').map(ToString::to_string).collect();
if vals.len() > 3 {
Ok(Self::Detail {
full_name: vals[0].clone(),
room: vals[1].clone(),
phone_work: vals[2].clone(),
phone_home: vals[3].clone(),
other: if vals.len() == 4 {
None
} else {
Some(vals[4..].to_vec())
},
})
} else if vals.len() == 1 {
Ok(Self::Simple {
comment: vals.get(0).unwrap().into(),
})
} else {
panic!(format!("Could not parse this string: {}", source))
}
}
}
#[test]
fn test_parse_gecos() {
let gcdetail = "Full Name,504,11345342,ä1-2312,myemail@test.com".to_string();
let gcsimple = "A böring comment →".to_string();
let gc_no_other = "systemd Network Management,,,".to_string();
let res_detail = crate::Gecos::try_from(gcdetail).unwrap();
let res_simple = crate::Gecos::try_from(gcsimple).unwrap();
let res_no_other = crate::Gecos::try_from(gc_no_other).unwrap();
match res_simple {
crate::Gecos::Simple { comment } => assert_eq!(comment, "A böring comment →"),
_ => unreachable!(),
}
match res_detail {
crate::Gecos::Detail {
full_name,
room,
phone_work,
phone_home,
other,
} => {
assert_eq!(full_name, "Full Name");
assert_eq!(room, "504");
assert_eq!(phone_work, "11345342");
assert_eq!(phone_home, "ä1-2312");
assert_eq!(other.unwrap()[0], "myemail@test.com");
}
_ => unreachable!(),
}
match res_no_other {
crate::Gecos::Detail {
full_name,
room,
phone_work,
phone_home,
other,
} => {
assert_eq!(full_name, "systemd Network Management");
assert_eq!(room, "");
assert_eq!(phone_work, "");
assert_eq!(phone_home, "");
assert_eq!(other, None);
}
_ => unreachable!(),
}
}
#[test]
fn test_gecos_getters() {
let gcdetail = "Full Name,504,11345342,ä1-2312,myemail@test.com".to_string();
let gcsimple = "A böring comment →".to_string();
let gc_no_other = "systemd Network Management,,,".to_string();
let res_detail = crate::Gecos::try_from(gcdetail).unwrap();
let res_simple = crate::Gecos::try_from(gcsimple).unwrap();
let res_no_other = crate::Gecos::try_from(gc_no_other).unwrap();
assert_eq!(res_simple.get_comment(), Some("A böring comment →"));
assert_eq!(res_detail.get_comment(), None);
assert_eq!(res_detail.get_full_name(), Some("Full Name"));
assert_eq!(res_detail.get_room(), Some("504"));
assert_eq!(res_detail.get_phone_work(), Some("11345342"));
assert_eq!(res_detail.get_phone_home(), Some("ä1-2312"));
assert_eq!(
res_detail.get_other(),
Some(&vec!["myemail@test.com".to_string()])
);
assert_eq!(
res_no_other.get_full_name(),
Some("systemd Network Management")
);
assert_eq!(res_no_other.get_room(), None);
assert_eq!(res_no_other.get_phone_work(), None);
assert_eq!(res_no_other.get_phone_home(), None);
assert_eq!(res_no_other.get_other(), None);
}