Skip to main content

rust_eureka/request/
leaseinfo.rs

1use serde::de::{Deserialize, Deserializer, Error as DeError, MapAccess, Visitor};
2use serde::ser::{Serialize, SerializeStruct, Serializer};
3use std::fmt;
4
5const LEASE_INFO: &str = "LeaseInfo";
6const EVICTION_DURATION_IN_SECS: &str = "evictionDurationInSecs";
7const FIELDS: &[&str] = &[EVICTION_DURATION_IN_SECS];
8
9#[derive(Debug, PartialEq)]
10pub struct LeaseInfo {
11    pub eviction_duration_in_secs: Option<u32>,
12}
13
14impl Serialize for LeaseInfo {
15    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
16    where
17        S: Serializer,
18    {
19        let mut s = serializer.serialize_struct(LEASE_INFO, 1)?;
20        // if not specified we will serialize the default of 90
21        let result = self.eviction_duration_in_secs.unwrap_or(90);
22        s.serialize_field(EVICTION_DURATION_IN_SECS, &result)?;
23        s.end()
24    }
25}
26
27impl<'de> Deserialize<'de> for LeaseInfo {
28    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
29    where
30        D: Deserializer<'de>,
31    {
32        enum Field {
33            EvictionDurationInSecs,
34        }
35
36        impl<'de> Deserialize<'de> for Field {
37            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
38            where
39                D: Deserializer<'de>,
40            {
41                struct FieldVisitor;
42
43                impl<'de> Visitor<'de> for FieldVisitor {
44                    type Value = Field;
45
46                    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
47                        formatter.write_str("Expecting eviction_duration_in_secs")
48                    }
49
50                    fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
51                    where
52                        E: DeError,
53                    {
54                        match v {
55                            EVICTION_DURATION_IN_SECS => Ok(Field::EvictionDurationInSecs),
56                            _ => Err(DeError::unknown_field(v, FIELDS)),
57                        }
58                    }
59                }
60                deserializer.deserialize_identifier(FieldVisitor)
61            }
62        }
63
64        struct LeaseInfoVisitor;
65
66        impl<'de> Visitor<'de> for LeaseInfoVisitor {
67            type Value = LeaseInfo;
68
69            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
70                formatter.write_str("struct LeaseInfoVisitor")
71            }
72            fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
73            where
74                A: MapAccess<'de>,
75            {
76                let mut maybe_eviction_duration = None;
77
78                while let Some(key) = map.next_key()? {
79                    match key {
80                        Field::EvictionDurationInSecs => {
81                            if maybe_eviction_duration.is_some() {
82                                return Err(DeError::duplicate_field(EVICTION_DURATION_IN_SECS));
83                            }
84                            maybe_eviction_duration = Some(map.next_value()?);
85                        }
86                    }
87                }
88                Ok(LeaseInfo {
89                    eviction_duration_in_secs: maybe_eviction_duration,
90                })
91            }
92        }
93
94        deserializer.deserialize_struct(LEASE_INFO, FIELDS, LeaseInfoVisitor)
95    }
96}
97
98#[cfg(test)]
99mod test {
100    use super::*;
101    use serde_json;
102
103    #[test]
104    fn test_lease_info_some() {
105        let li = LeaseInfo {
106            eviction_duration_in_secs: Some(9600),
107        };
108        let json = r#"{"evictionDurationInSecs":9600}"#;
109        let result = serde_json::to_string(&li).unwrap();
110        assert_eq!(json, result);
111    }
112
113    #[test]
114    fn test_lease_info_none() {
115        let li = LeaseInfo {
116            eviction_duration_in_secs: None,
117        };
118        let json = r#"{"evictionDurationInSecs":90}"#;
119        let result = serde_json::to_string(&li).unwrap();
120        assert_eq!(json, result);
121    }
122
123    #[test]
124    fn test_deserialize_lease_info_some() {
125        let li = LeaseInfo {
126            eviction_duration_in_secs: Some(90),
127        };
128        let json = r#"{"evictionDurationInSecs":90}"#;
129        let result = serde_json::from_str(json).unwrap();
130        assert_eq!(li, result);
131    }
132}