rust_eureka/request/
status.rs

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