Skip to main content

rust_eureka/response/
action_type.rs

1use serde::de::{Deserialize, Deserializer, Error as DeError, Visitor};
2use serde::ser::{Serialize, Serializer};
3use std::convert::From;
4use std::error::Error;
5use std::fmt;
6use std::str::FromStr;
7
8const ADDED: &str = "ADDED";
9const DELETED: &str = "DELETED";
10const MODIFIED: &str = "MODIFIED";
11
12#[derive(Debug, PartialEq)]
13pub enum ActionType {
14    Added,
15    Deleted,
16    Modified,
17}
18
19impl ActionType {
20    fn values() -> Vec<ActionType> {
21        use self::ActionType::*;
22        vec![Added, Deleted, Modified]
23    }
24}
25
26#[derive(Debug)]
27pub struct InvalidActionTypeError {
28    invalid_value: String,
29}
30
31impl InvalidActionTypeError {
32    pub fn new(invalid_nm: &str) -> Self {
33        InvalidActionTypeError {
34            invalid_value: invalid_nm.to_owned(),
35        }
36    }
37}
38
39impl fmt::Display for InvalidActionTypeError {
40    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41        write!(f, "InvalidActionTypeError({})", self.invalid_value)
42    }
43}
44
45impl Error for InvalidActionTypeError {
46    fn description(&self) -> &str {
47        "Not a valid ActionType"
48    }
49}
50
51impl FromStr for ActionType {
52    type Err = InvalidActionTypeError;
53
54    fn from_str(s: &str) -> Result<Self, Self::Err> {
55        match s {
56            ADDED => Ok(ActionType::Added),
57            DELETED => Ok(ActionType::Deleted),
58            MODIFIED => Ok(ActionType::Modified),
59            _ => Err(InvalidActionTypeError::new(s)),
60        }
61    }
62}
63
64impl From<ActionType> for String {
65    fn from(s: ActionType) -> Self {
66        match s {
67            ActionType::Added => ADDED.to_string(),
68            ActionType::Deleted => DELETED.to_string(),
69            ActionType::Modified => MODIFIED.to_string(),
70        }
71    }
72}
73
74impl From<&ActionType> for String {
75    fn from(s: &ActionType) -> Self {
76        match *s {
77            ActionType::Added => ADDED.to_string(),
78            ActionType::Deleted => DELETED.to_string(),
79            ActionType::Modified => MODIFIED.to_string(),
80        }
81    }
82}
83
84impl Serialize for ActionType {
85    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
86    where
87        S: Serializer,
88    {
89        serializer.serialize_str(String::from(self).as_ref())
90    }
91}
92
93impl<'de> Deserialize<'de> for ActionType {
94    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
95    where
96        D: Deserializer<'de>,
97    {
98        struct ActionTypeVisitor;
99
100        impl<'de> Visitor<'de> for ActionTypeVisitor {
101            type Value = ActionType;
102
103            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
104                let values = ActionType::values()
105                    .iter()
106                    .fold(String::new(), |mut acc, v| {
107                        acc.push_str(String::from(v).as_ref());
108                        acc
109                    });
110
111                formatter.write_fmt(format_args!("Expecting {}", values))
112            }
113
114            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
115            where
116                E: DeError,
117            {
118                ActionType::from_str(v).map_err(|err| E::custom(format!("{}", err)))
119            }
120        }
121
122        deserializer.deserialize_str(ActionTypeVisitor)
123    }
124}
125
126#[cfg(test)]
127mod test {
128    use super::*;
129
130    #[test]
131    fn test_from_str() {
132        assert_eq!(ActionType::Added, ActionType::from_str(ADDED).unwrap());
133        assert_eq!(ActionType::Deleted, ActionType::from_str(DELETED).unwrap());
134        assert_eq!(
135            ActionType::Modified,
136            ActionType::from_str(MODIFIED).unwrap()
137        );
138    }
139
140    #[test]
141    #[should_panic]
142    fn test_from_str_invalid() {
143        ActionType::from_str("sfd2ef").unwrap();
144    }
145
146    #[test]
147    fn test_to_string() {
148        assert_eq!(ADDED.to_owned(), String::from(ActionType::Added));
149        assert_eq!(DELETED.to_owned(), String::from(ActionType::Deleted));
150        assert_eq!(MODIFIED.to_owned(), String::from(ActionType::Modified));
151    }
152}