seq_marked/seqv/
mod.rs

1mod impl_from_seq_data;
2mod impl_from_seq_marked;
3mod impl_seq_value;
4
5use std::fmt;
6use std::ops::Deref;
7use std::ops::DerefMut;
8
9/// Some value bound with a seq number.
10///
11/// [`SeqV`] is the meta-service API level generic value.
12/// Meta-service application uses this type to interact with meta-service.
13///
14/// Inside the meta-service, the value is stored in the form of `Marked`, which could be a
15/// tombstone. A `Marked::TombStone` is converted to `None::<SeqV>` and a `Marked::Normal` is
16/// converted to `Some::<SeqV>`.
17///
18/// A `Marked::TombStone` also has an `internal_seq`, representing the freshness of the tombstone.
19/// `internal_seq` will be discarded when `Marked::TombStone` is converted to `None::<SeqV>`.
20#[derive(Default, Clone, Eq, PartialEq)]
21#[cfg_attr(feature = "seqv-serde", derive(serde::Serialize, serde::Deserialize))]
22pub struct SeqV<M, T = Vec<u8>> {
23    pub seq: u64,
24    pub meta: Option<M>,
25    pub data: T,
26}
27
28impl<M, T> Deref for SeqV<M, T> {
29    type Target = T;
30
31    fn deref(&self) -> &Self::Target {
32        &self.data
33    }
34}
35
36impl<M, T> DerefMut for SeqV<M, T> {
37    fn deref_mut(&mut self) -> &mut Self::Target {
38        &mut self.data
39    }
40}
41
42impl<M, T> fmt::Debug for SeqV<M, T>
43where
44    M: fmt::Debug,
45    T: fmt::Debug,
46{
47    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
48        let mut de = f.debug_struct("SeqV");
49        de.field("seq", &self.seq);
50        de.field("meta", &self.meta);
51        de.field("data", &"[binary]");
52
53        de.finish()
54    }
55}
56
57impl<M, T> SeqV<M, T> {
58    pub fn new(seq: u64, data: T) -> Self {
59        Self {
60            seq,
61            meta: None,
62            data,
63        }
64    }
65
66    pub fn new_with_meta(seq: u64, meta: Option<M>, data: T) -> Self {
67        Self { seq, meta, data }
68    }
69
70    #[must_use]
71    pub fn with_seq(mut self, seq: u64) -> Self {
72        self.seq = seq;
73        self
74    }
75
76    #[must_use]
77    pub fn with_meta(mut self, m: Option<M>) -> Self {
78        self.meta = m;
79        self
80    }
81
82    #[must_use]
83    pub fn with_value(mut self, v: T) -> Self {
84        self.data = v;
85        self
86    }
87
88    /// Convert data to type U and leave seq and meta unchanged.
89    pub fn map<U>(self, f: impl FnOnce(T) -> U) -> SeqV<M, U> {
90        SeqV {
91            seq: self.seq,
92            meta: self.meta,
93            data: f(self.data),
94        }
95    }
96
97    /// Try to convert data to type U and leave seq and meta unchanged.
98    /// `f` returns an error if the conversion fails.
99    pub fn try_map<U, E>(self, f: impl FnOnce(T) -> Result<U, E>) -> Result<SeqV<M, U>, E> {
100        Ok(SeqV {
101            seq: self.seq,
102            meta: self.meta,
103            data: f(self.data)?,
104        })
105    }
106}
107
108#[cfg(test)]
109mod tests {
110    use super::*;
111
112    #[test]
113    fn test_new() {
114        let sv = SeqV::<(), _>::new(42, 100u64);
115        assert_eq!(sv.seq, 42);
116        assert_eq!(sv.meta, None);
117        assert_eq!(sv.data, 100);
118    }
119
120    #[test]
121    fn test_new_with_meta() {
122        let sv = SeqV::new_with_meta(10, Some("metadata"), 200u64);
123        assert_eq!(sv.seq, 10);
124        assert_eq!(sv.meta, Some("metadata"));
125        assert_eq!(sv.data, 200);
126
127        let sv_none = SeqV::new_with_meta(5, None::<String>, 300u64);
128        assert_eq!(sv_none.meta, None);
129    }
130
131    #[test]
132    fn test_builder_methods() {
133        let sv = SeqV::new(1, 100u64).with_seq(42).with_meta(Some("test")).with_value(200u64);
134
135        assert_eq!(sv.seq, 42);
136        assert_eq!(sv.meta, Some("test"));
137        assert_eq!(sv.data, 200);
138    }
139
140    #[test]
141    fn test_map() {
142        let sv = SeqV::new_with_meta(10, Some("meta"), 5u64);
143        let mapped = sv.map(|x| x * 2);
144
145        assert_eq!(mapped.seq, 10);
146        assert_eq!(mapped.meta, Some("meta"));
147        assert_eq!(mapped.data, 10u64);
148    }
149
150    #[test]
151    fn test_try_map_success() {
152        let sv = SeqV::new_with_meta(20, Some("meta"), "123");
153        let result = sv.try_map(|s| s.parse::<u64>());
154
155        assert!(result.is_ok());
156        let mapped = result.unwrap();
157        assert_eq!(mapped.seq, 20);
158        assert_eq!(mapped.meta, Some("meta"));
159        assert_eq!(mapped.data, 123u64);
160    }
161
162    #[test]
163    fn test_try_map_error() {
164        let sv = SeqV::<(), _>::new(30, "invalid");
165        let result = sv.try_map(|s| s.parse::<u64>());
166
167        assert!(result.is_err());
168    }
169
170    #[test]
171    fn test_deref() {
172        let sv = SeqV::<(), _>::new(1, vec![1, 2, 3]);
173        assert_eq!(sv.len(), 3);
174        assert_eq!(sv[0], 1);
175    }
176
177    #[test]
178    fn test_deref_mut() {
179        let mut sv = SeqV::<(), _>::new(1, vec![1, 2, 3]);
180        sv[0] = 10;
181        assert_eq!(sv.data[0], 10);
182    }
183
184    #[test]
185    fn test_default() {
186        let sv = SeqV::<String, u64>::default();
187        assert_eq!(sv.seq, 0);
188        assert_eq!(sv.meta, None);
189        assert_eq!(sv.data, 0);
190    }
191
192    #[test]
193    fn test_debug() {
194        let sv = SeqV::new_with_meta(42, Some("test"), vec![1, 2, 3]);
195        assert_eq!(
196            "SeqV { seq: 42, meta: Some(\"test\"), data: \"[binary]\" }",
197            format!("{:?}", sv)
198        );
199    }
200
201    #[test]
202    fn test_clone_eq() {
203        let sv1 = SeqV::new_with_meta(10, Some("meta"), 100u64);
204        let sv2 = sv1.clone();
205        assert_eq!(sv1, sv2);
206    }
207}
208
209#[cfg(test)]
210#[cfg(feature = "seqv-serde")]
211mod tests_serde {
212    use serde_json;
213
214    use super::*;
215
216    #[test]
217    fn test_serde() {
218        let sv = SeqV::new_with_meta(42, Some("metadata".to_string()), vec![1, 2, 3]);
219        let json = serde_json::to_string(&sv).unwrap();
220        let deserialized: SeqV<String, Vec<u8>> = serde_json::from_str(&json).unwrap();
221        assert_eq!(sv, deserialized);
222
223        // Test with None metadata
224        let sv_none = SeqV::new_with_meta(10, None::<String>, vec![4, 5, 6]);
225        let json_none = serde_json::to_string(&sv_none).unwrap();
226        let deserialized_none: SeqV<String, Vec<u8>> = serde_json::from_str(&json_none).unwrap();
227        assert_eq!(sv_none, deserialized_none);
228    }
229}