Skip to main content

eml_nl/utils/
gender.rs

1use thiserror::Error;
2
3use crate::{EMLError, EMLValueResultExt as _, utils::StringValueData};
4
5/// Gender of a candidate.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub enum Gender {
8    /// Male gender
9    Male,
10    /// Female gender
11    Female,
12    /// Gender unknown
13    Unknown,
14}
15
16impl Gender {
17    /// Create a new Gender from a string, validating its format.
18    pub fn new(s: impl AsRef<str>) -> Result<Self, EMLError> {
19        Self::from_eml_value(s).wrap_value_error()
20    }
21
22    /// Create a Gender from a `&str`, if possible.
23    pub fn from_eml_value(s: impl AsRef<str>) -> Result<Self, UnknownGenderError> {
24        let data = s.as_ref();
25        match data {
26            "male" => Ok(Gender::Male),
27            "female" => Ok(Gender::Female),
28            "unknown" => Ok(Gender::Unknown),
29            _ => Err(UnknownGenderError(data.to_string())),
30        }
31    }
32
33    /// Get the `&str` representation of this Gender.
34    pub fn to_eml_value(&self) -> &'static str {
35        match self {
36            Gender::Male => "male",
37            Gender::Female => "female",
38            Gender::Unknown => "unknown",
39        }
40    }
41}
42
43/// Error returned when an unknown gender string is encountered.
44#[derive(Debug, Clone, Error, PartialEq, Eq)]
45#[error("Unknown gender: {0}")]
46pub struct UnknownGenderError(String);
47
48impl StringValueData for Gender {
49    type Error = UnknownGenderError;
50
51    fn parse_from_str(s: &str) -> Result<Self, Self::Error>
52    where
53        Self: Sized,
54    {
55        Self::from_eml_value(s)
56    }
57
58    fn to_raw_value(&self) -> String {
59        self.to_eml_value().to_string()
60    }
61}
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66
67    #[test]
68    fn test_valid_gender_types() {
69        let valid_genders = ["male", "female", "unknown"];
70        for gender in valid_genders {
71            assert!(
72                Gender::from_eml_value(gender).is_ok(),
73                "Gender should accept valid gender: {}",
74                gender
75            );
76        }
77    }
78
79    #[test]
80    fn test_invalid_gender_types() {
81        let invalid_genders = ["", "test", "abc"];
82        for gender in invalid_genders {
83            assert!(
84                Gender::from_eml_value(gender).is_err(),
85                "Gender should reject invalid gender: {}",
86                gender
87            );
88        }
89    }
90}