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