1use std::fmt;
2
3use crate::InternalSeq;
4use crate::SeqMarked;
5
6mod impl_from_seq_marked;
7
8#[derive(Debug)]
18#[derive(Clone, Copy)]
19#[derive(PartialEq, Eq)]
20#[derive(PartialOrd, Ord)]
21#[cfg_attr(
22 feature = "seq-marked-serde",
23 derive(serde::Serialize, serde::Deserialize)
24)]
25#[cfg_attr(
26 feature = "seq-marked-bincode",
27 derive(bincode::Encode, bincode::Decode)
28)]
29pub struct SeqData<D = Vec<u8>> {
30 seq: u64,
32 data: D,
33}
34
35impl<D> SeqData<D> {
36 pub fn new(seq: u64, data: D) -> Self {
38 Self { seq, data }
39 }
40
41 pub fn map<U>(self, f: impl FnOnce(D) -> U) -> SeqData<U> {
53 SeqData {
54 seq: self.seq,
55 data: f(self.data),
56 }
57 }
58
59 pub fn try_map<U, E>(self, f: impl FnOnce(D) -> Result<U, E>) -> Result<SeqData<U>, E> {
60 Ok(SeqData {
61 seq: self.seq,
62 data: f(self.data)?,
63 })
64 }
65
66 pub fn as_ref(&self) -> SeqData<&D> {
68 SeqData {
69 seq: self.seq,
70 data: &self.data,
71 }
72 }
73
74 pub fn order_key(&self) -> SeqMarked<()> {
76 SeqMarked::new_normal(self.seq, ())
77 }
78
79 pub fn internal_seq(&self) -> InternalSeq {
81 InternalSeq::new(self.seq)
82 }
83
84 pub fn user_seq(&self) -> u64 {
86 self.seq
87 }
88
89 pub fn max(a: Self, b: Self) -> Self {
91 if a.order_key() > b.order_key() { a } else { b }
92 }
93
94 pub fn max_ref<'l>(a: &'l Self, b: &'l Self) -> &'l Self {
96 if a.order_key() > b.order_key() { a } else { b }
97 }
98
99 pub fn data(&self) -> &D {
101 &self.data
102 }
103
104 pub fn into_data(self) -> D {
106 self.data
107 }
108
109 pub fn into_parts(self) -> (u64, D) {
110 (self.seq, self.data)
111 }
112
113 pub fn display_with_debug(&self) -> impl fmt::Display + '_
115 where D: fmt::Debug {
116 struct DisplaySeqData<'a, D>(&'a SeqData<D>);
117
118 impl<D> fmt::Display for DisplaySeqData<'_, D>
119 where D: fmt::Debug
120 {
121 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
122 write!(f, "{{seq: {}, ", self.0.seq)?;
123 write!(f, "({:?})", self.0.data)?;
124 write!(f, "}}")
125 }
126 }
127
128 DisplaySeqData(self)
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use std::cmp::Ordering;
135
136 use Ordering::Equal;
137 use Ordering::Greater;
138 use Ordering::Less;
139
140 use super::*;
141 use crate::testing::ts;
142
143 pub(crate) fn norm<D>(seq: u64, d: D) -> SeqData<D> {
145 SeqData::new(seq, d)
146 }
147
148 #[test]
149 fn test_seq_data_is_copy() {
150 let seq_marked = SeqData::new(5, "data");
151 let seq_marked_copy = seq_marked;
152 assert_eq!(seq_marked, seq_marked_copy);
153 }
154
155 #[test]
156 fn test_new() {
157 let seq_marked = SeqData::new(5, "data");
158 assert_eq!(seq_marked.seq, 5);
159 assert_eq!(seq_marked.data, "data");
160 }
161
162 #[test]
163 fn test_map() -> anyhow::Result<()> {
164 let a = norm(1, 1u64);
165 assert_eq!(norm(1, 2u32), a.map(|x| (x * 2) as u32));
166
167 let a = ts::<u64>(1);
168 assert_eq!(ts::<u32>(1), a.map(|x| (x * 2) as u32));
169
170 Ok(())
171 }
172
173 #[test]
174 fn test_as_ref() -> anyhow::Result<()> {
175 let a = norm(1, 1u64);
176 assert_eq!(norm(1, &1u64), a.as_ref());
177
178 let a = ts::<u64>(1);
179 assert_eq!(ts::<&u64>(1), a.as_ref());
180
181 Ok(())
182 }
183
184 #[test]
185 fn test_order_key() -> anyhow::Result<()> {
186 assert!(norm(1, 1u64).order_key() == norm(1, 1u64).order_key());
187 assert!(norm(1, 2u64).order_key() == norm(1, 1u64).order_key());
188 assert!(norm(2, 2u64).order_key() > norm(1, 1u64).order_key());
189
190 assert!(ts::<u64>(1).order_key() > norm(1, 1u64).order_key());
191 assert!(ts::<u64>(2).order_key() > norm(1, 1u64).order_key());
192
193 assert!(ts::<u64>(2).order_key() > ts::<u64>(1).order_key());
194 assert!(ts::<u64>(1).order_key() == ts::<u64>(1).order_key());
195
196 Ok(())
197 }
198
199 #[test]
200 fn test_partial_ord() -> anyhow::Result<()> {
201 fn pcmp<D: PartialOrd>(a: &SeqData<D>, b: &SeqData<D>) -> Option<Ordering> {
202 PartialOrd::partial_cmp(a, b)
203 }
204
205 assert_eq!(Some(Greater), pcmp(&norm(2, 2u64), &norm(1, 2u64)));
208 assert_eq!(Some(Equal), pcmp(&norm(2, 2u64), &norm(2, 2u64)));
209 assert_eq!(Some(Less), pcmp(&norm(2, 2u64), &norm(3, 2u64)));
210
211 assert_eq!(Some(Greater), pcmp(&norm(2, 2u64), &norm(2, 1u64)));
214 assert_eq!(Some(Equal), pcmp(&norm(2, 2u64), &norm(2, 2u64)));
215 assert_eq!(Some(Less), pcmp(&norm(2, 2u64), &norm(2, 3u64)));
216
217 Ok(())
218 }
219
220 #[test]
221 fn test_seq_data_order_key() {
222 let a = SeqData::new(1, "data1");
223
224 assert_eq!(a.order_key(), SeqMarked::new_normal(1, ()));
225 }
226
227 #[test]
228 fn test_max() {
229 assert_eq!(
230 SeqData::<u64>::new(2, 1),
231 SeqData::<u64>::max(SeqData::<u64>::new(1, 1), SeqData::<u64>::new(2, 1))
232 );
233 assert_eq!(
234 SeqData::<u64>::new(2, 1),
235 SeqData::<u64>::max(SeqData::<u64>::new(1, 2), SeqData::<u64>::new(2, 1))
236 );
237 }
238
239 #[test]
240 fn test_max_ref() {
241 let m1 = SeqData::new(1, 2);
242 let m2 = SeqData::new(3, 2);
243
244 assert_eq!(SeqData::max_ref(&m1, &m2), &m2);
245
246 assert_eq!(SeqData::max_ref(&m1, &m1), &m1);
247 assert_eq!(SeqData::max_ref(&m2, &m2), &m2);
248 }
249
250 #[test]
251 fn test_into_parts() {
252 let seq_marked = SeqData::new(5, "data");
253 let (seq, marked) = seq_marked.into_parts();
254 assert_eq!(seq, 5);
255 assert_eq!(marked, "data");
256 }
257
258 #[test]
259 fn test_internal_seq() {
260 let seq_marked = SeqData::new(5, "data");
261 assert_eq!(*seq_marked.internal_seq(), 5);
262 }
263
264 #[test]
265 fn test_user_seq() {
266 let seq_marked = SeqData::new(5, "data");
267 assert_eq!(seq_marked.user_seq(), 5);
268 }
269
270 #[test]
271 fn test_display_with_debug() {
272 let seq_marked = SeqData::new(5, "data");
273 assert_eq!(
274 format!("{}", seq_marked.display_with_debug()),
275 "{seq: 5, (\"data\")}"
276 );
277 }
278}
279
280#[cfg(test)]
281#[cfg(feature = "seq-marked-bincode")]
282mod tests_bincode {
283
284 use super::*;
285 use crate::testing::bincode_config;
286 use crate::testing::test_bincode_decode;
287
288 #[test]
289 fn test_marked_bincode() {
290 let a = SeqData::new(5, 1u64);
291 let encoded = bincode::encode_to_vec(&a, bincode_config()).unwrap();
292 let (decoded, n): (SeqData<u64>, usize) =
293 bincode::decode_from_slice(&encoded, bincode_config()).unwrap();
294 assert_eq!(n, 2);
295 assert_eq!(a, decoded);
296 }
297
298 #[test]
299 fn test_marked_bincode_decode_v010() -> anyhow::Result<()> {
300 let value = SeqData::new(5, 1u64);
301 let encoded = vec![5, 1];
302
303 test_bincode_decode(&encoded, &value)?;
304
305 Ok(())
306 }
307}
308
309#[cfg(test)]
310#[cfg(feature = "seq-marked-serde")]
311mod tests_serde {
312 use super::*;
313 use crate::testing::test_serde_decode;
314
315 #[test]
316 fn test_marked_serde() {
317 let a = SeqData::new(5, 1u64);
318 let encoded = serde_json::to_string(&a).unwrap();
319 let decoded: SeqData<u64> = serde_json::from_str(&encoded).unwrap();
320 assert_eq!(a, decoded);
321 }
322
323 #[test]
324 fn test_marked_serde_decode_v010() -> anyhow::Result<()> {
325 let value = SeqData::new(5, 1u64);
326 let encoded = r#"{"seq":5,"data":1}"#;
327
328 test_serde_decode(encoded, &value)?;
329
330 Ok(())
331 }
332}