aldrin_core/
service_info.rs

1#[cfg(test)]
2mod test_old1;
3
4use crate::tags::{self, PrimaryTag, Tag};
5use crate::{
6    Deserialize, DeserializeError, Deserializer, Serialize, SerializeError, Serializer, TypeId,
7};
8use num_enum::{IntoPrimitive, TryFromPrimitive};
9
10#[derive(IntoPrimitive, TryFromPrimitive)]
11#[repr(u32)]
12enum ServiceInfoField {
13    Version = 0,
14    TypeId = 1,
15    SubscribeAll = 2,
16}
17
18#[derive(Debug, Copy, Clone, PartialEq, Eq)]
19pub struct ServiceInfo {
20    version: u32,
21    type_id: Option<TypeId>,
22    subscribe_all: Option<bool>,
23}
24
25impl ServiceInfo {
26    pub fn new(version: u32) -> Self {
27        Self {
28            version,
29            type_id: None,
30            subscribe_all: None,
31        }
32    }
33
34    pub fn version(self) -> u32 {
35        self.version
36    }
37
38    #[must_use = "this method follows the builder pattern and returns a new `ServiceInfo`"]
39    pub fn set_version(mut self, version: u32) -> Self {
40        self.version = version;
41        self
42    }
43
44    pub fn type_id(self) -> Option<TypeId> {
45        self.type_id
46    }
47
48    #[must_use = "this method follows the builder pattern and returns a new `ServiceInfo`"]
49    pub fn set_type_id(mut self, type_id: TypeId) -> Self {
50        self.type_id = Some(type_id);
51        self
52    }
53
54    pub fn subscribe_all(self) -> Option<bool> {
55        self.subscribe_all
56    }
57
58    #[must_use = "this method follows the builder pattern and returns a new `ServiceInfo`"]
59    pub fn set_subscribe_all(mut self, subscribe_all: bool) -> Self {
60        self.subscribe_all = Some(subscribe_all);
61        self
62    }
63}
64
65impl Tag for ServiceInfo {}
66
67impl PrimaryTag for ServiceInfo {
68    type Tag = Self;
69}
70
71impl Serialize<Self> for ServiceInfo {
72    fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
73        let mut serializer = serializer.serialize_struct2()?;
74
75        serializer.serialize::<tags::U32>(ServiceInfoField::Version, self.version)?;
76
77        serializer
78            .serialize_if_some::<tags::Option<TypeId>>(ServiceInfoField::TypeId, self.type_id)?;
79
80        serializer.serialize_if_some::<tags::Option<tags::Bool>>(
81            ServiceInfoField::SubscribeAll,
82            self.subscribe_all,
83        )?;
84
85        serializer.finish()
86    }
87}
88
89impl Serialize<ServiceInfo> for &ServiceInfo {
90    fn serialize(self, serializer: Serializer) -> Result<(), SerializeError> {
91        serializer.serialize(*self)
92    }
93}
94
95impl Deserialize<Self> for ServiceInfo {
96    fn deserialize(deserializer: Deserializer) -> Result<Self, DeserializeError> {
97        let mut deserializer = deserializer.deserialize_struct()?;
98
99        let mut version = None;
100        let mut type_id = None;
101        let mut subscribe_all = None;
102
103        while let Some(deserializer) = deserializer.deserialize()? {
104            match deserializer.try_id() {
105                Ok(ServiceInfoField::Version) => {
106                    version = deserializer.deserialize::<tags::U32, _>().map(Some)?
107                }
108
109                Ok(ServiceInfoField::TypeId) => {
110                    type_id = deserializer.deserialize::<tags::Option<TypeId>, _>()?
111                }
112
113                Ok(ServiceInfoField::SubscribeAll) => {
114                    subscribe_all = deserializer.deserialize::<tags::Option<tags::Bool>, _>()?
115                }
116
117                Err(_) => deserializer.skip()?,
118            }
119        }
120
121        deserializer.finish_with(|_| {
122            Ok(Self {
123                version: version.ok_or(DeserializeError::InvalidSerialization)?,
124                type_id,
125                subscribe_all,
126            })
127        })
128    }
129}
130
131#[cfg(test)]
132mod test {
133    use super::ServiceInfo;
134    use crate::{SerializedValue, TypeId};
135    use uuid::uuid;
136
137    fn serde(info: ServiceInfo) -> ServiceInfo {
138        SerializedValue::serialize(info)
139            .unwrap()
140            .deserialize()
141            .unwrap()
142    }
143
144    #[test]
145    fn serialize() {
146        let info = ServiceInfo::new(1);
147        assert_eq!(info, serde(info));
148
149        let info =
150            ServiceInfo::new(1).set_type_id(TypeId(uuid!("88e82fb9-03b2-4f51-94d8-4702cfacc90c")));
151        assert_eq!(info, serde(info));
152
153        let info = ServiceInfo::new(1).set_subscribe_all(true);
154        assert_eq!(info, serde(info));
155
156        let info = ServiceInfo::new(1)
157            .set_type_id(TypeId(uuid!("88e82fb9-03b2-4f51-94d8-4702cfacc90c")))
158            .set_subscribe_all(true);
159        assert_eq!(info, serde(info));
160    }
161}