Skip to main content

rust_eureka/request/
status.rs

1use serde::de::{Deserialize, Deserializer, Error as DeError, Visitor};
2use serde::ser::{Serialize, Serializer};
3use std::convert::From;
4use std::fmt;
5use std::iter::Iterator;
6
7const UP: &str = "UP";
8const DOWN: &str = "DOWN";
9const STARTING: &str = "STARTING";
10const OUT_OF_SERVICE: &str = "OUT_OF_SERVICE";
11const UNKNOWN: &str = "UNKNOWN";
12
13#[derive(Debug, PartialEq)]
14pub enum Status {
15    Up,
16    Down,
17    Starting,
18    OutOfService,
19    Unknown,
20}
21
22impl Status {
23    fn values() -> Vec<Status> {
24        use self::Status::*;
25        vec![Up, Down, Starting, OutOfService]
26    }
27}
28
29impl From<&str> for Status {
30    fn from(str: &str) -> Self {
31        match str {
32            UP => Status::Up,
33            DOWN => Status::Down,
34            STARTING => Status::Starting,
35            OUT_OF_SERVICE => Status::OutOfService,
36            _ => Status::Unknown,
37        }
38    }
39}
40
41impl From<String> for Status {
42    fn from(s: String) -> Self {
43        Status::from(s.as_ref())
44    }
45}
46
47impl From<Status> for String {
48    fn from(s: Status) -> Self {
49        match s {
50            Status::Up => UP.to_string(),
51            Status::Down => DOWN.to_string(),
52            Status::Starting => STARTING.to_string(),
53            Status::OutOfService => OUT_OF_SERVICE.to_string(),
54            _ => UNKNOWN.to_string(),
55        }
56    }
57}
58
59impl From<&Status> for String {
60    fn from(s: &Status) -> Self {
61        match *s {
62            Status::Up => UP.to_string(),
63            Status::Down => DOWN.to_string(),
64            Status::Starting => STARTING.to_string(),
65            Status::OutOfService => OUT_OF_SERVICE.to_string(),
66            Status::Unknown => UNKNOWN.to_string(),
67        }
68    }
69}
70
71impl Serialize for Status {
72    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
73    where
74        S: Serializer,
75    {
76        serializer.serialize_str(String::from(self).as_ref())
77    }
78}
79
80impl<'de> Deserialize<'de> for Status {
81    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
82    where
83        D: Deserializer<'de>,
84    {
85        struct StatusVisitor;
86
87        impl<'de> Visitor<'de> for StatusVisitor {
88            type Value = Status;
89
90            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
91                let values = Status::values().iter().fold(String::new(), |mut acc, v| {
92                    acc.push_str(String::from(v).as_ref());
93                    acc
94                });
95
96                formatter.write_fmt(format_args!("Expecting {}", values))
97            }
98
99            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
100            where
101                E: DeError,
102            {
103                Ok(From::from(v))
104            }
105        }
106
107        deserializer.deserialize_str(StatusVisitor)
108    }
109}
110
111#[cfg(test)]
112mod test {
113    use super::*;
114
115    #[test]
116    fn test_from_string_ref() {
117        let up = Status::from(UP);
118        assert_eq!(Status::Up, up);
119    }
120
121    #[test]
122    fn test_from_string() {
123        let up = Status::from(UP.to_owned());
124        assert_eq!(Status::Up, up);
125    }
126}