1mod impl_display;
2mod impl_from_seqv;
3mod impl_seq_value;
4mod impl_try_from_meta_bytes;
5
6use std::fmt;
7
8use crate::Marked;
9
10#[derive(Debug)]
22#[derive(Clone, Copy)]
23#[derive(PartialEq, Eq)]
24#[derive(PartialOrd, Ord)]
25#[cfg_attr(
26 feature = "seq-marked-serde",
27 derive(serde::Serialize, serde::Deserialize)
28)]
29#[cfg_attr(
30 feature = "seq-marked-bincode",
31 derive(bincode::Encode, bincode::Decode)
32)]
33pub struct SeqMarked<D = Vec<u8>> {
34 seq: u64,
36 marked: Marked<D>,
37}
38
39impl<D> SeqMarked<D> {
40 pub fn new(seq: u64, marked: Marked<D>) -> Self {
42 Self { seq, marked }
43 }
44
45 pub fn new_normal(seq: u64, data: D) -> Self {
47 Self {
48 seq,
49 marked: Marked::Normal(data),
50 }
51 }
52
53 pub fn new_tombstone(seq: u64) -> Self {
55 Self {
56 seq,
57 marked: Marked::TombStone,
58 }
59 }
60
61 pub fn new_not_found() -> Self {
63 Self {
64 seq: 0,
65 marked: Marked::TombStone,
66 }
67 }
68
69 pub fn is_normal(&self) -> bool {
71 !self.is_tombstone()
72 }
73
74 pub fn is_tombstone(&self) -> bool {
76 match self.marked {
77 Marked::Normal(_) => false,
78 Marked::TombStone => true,
79 }
80 }
81
82 pub fn is_not_found(&self) -> bool {
83 self.is_absent()
84 }
85
86 pub fn is_absent(&self) -> bool {
87 self.seq == 0 && self.is_tombstone()
88 }
89
90 pub fn map<U>(self, f: impl FnOnce(D) -> U) -> SeqMarked<U> {
102 SeqMarked {
103 seq: self.seq,
104 marked: match self.marked {
105 Marked::Normal(data) => Marked::<U>::Normal(f(data)),
106 Marked::TombStone => Marked::<U>::TombStone,
107 },
108 }
109 }
110
111 pub fn try_map<U, E>(self, f: impl FnOnce(D) -> Result<U, E>) -> Result<SeqMarked<U>, E> {
112 Ok(SeqMarked {
113 seq: self.seq,
114 marked: match self.marked {
115 Marked::Normal(data) => Marked::<U>::Normal(f(data)?),
116 Marked::TombStone => Marked::<U>::TombStone,
117 },
118 })
119 }
120
121 pub fn as_ref(&self) -> SeqMarked<&D> {
123 SeqMarked {
124 seq: self.seq,
125 marked: match &self.marked {
126 Marked::Normal(data) => Marked::Normal(data),
127 Marked::TombStone => Marked::TombStone,
128 },
129 }
130 }
131
132 pub fn order_key(&self) -> SeqMarked<()> {
134 SeqMarked {
135 seq: self.seq,
136 marked: match &self.marked {
137 Marked::Normal(_) => Marked::Normal(()),
138 Marked::TombStone => Marked::TombStone,
139 },
140 }
141 }
142
143 pub fn internal_seq(&self) -> u64 {
145 self.seq
146 }
147
148 pub fn user_seq(&self) -> u64 {
150 if self.is_tombstone() { 0 } else { self.seq }
151 }
152
153 pub fn max(a: Self, b: Self) -> Self {
155 if a.order_key() > b.order_key() { a } else { b }
156 }
157
158 pub fn max_ref<'l>(a: &'l Self, b: &'l Self) -> &'l Self {
160 if a.order_key() > b.order_key() { a } else { b }
161 }
162
163 pub fn data_ref(&self) -> Option<&D> {
165 match self.marked {
166 Marked::Normal(ref d) => Some(d),
167 Marked::TombStone => None,
168 }
169 }
170
171 pub fn into_data(self) -> Option<D> {
173 match self.marked {
174 Marked::Normal(data) => Some(data),
175 Marked::TombStone => None,
176 }
177 }
178
179 pub fn into_parts(self) -> (u64, Marked<D>) {
180 (self.seq, self.marked)
181 }
182
183 pub fn display_with_debug(&self) -> impl fmt::Display + '_
185 where D: fmt::Debug {
186 struct DisplaySeqMarked<'a, D>(&'a SeqMarked<D>);
187
188 impl<D> fmt::Display for DisplaySeqMarked<'_, D>
189 where D: fmt::Debug
190 {
191 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192 write!(f, "{{seq: {}, ", self.0.seq)?;
193 match &self.0.marked {
194 Marked::Normal(data) => write!(f, "({:?})", data)?,
195 Marked::TombStone => write!(f, "TOMBSTONE")?,
196 }
197 write!(f, "}}")
198 }
199 }
200
201 DisplaySeqMarked(self)
202 }
203}
204
205#[cfg(test)]
206mod tests {
207 use std::cmp::Ordering;
208
209 use Ordering::Equal;
210 use Ordering::Greater;
211 use Ordering::Less;
212
213 use super::*;
214 use crate::testing::norm;
215 use crate::testing::ts;
216
217 #[test]
218 fn test_seq_marked_is_copy() {
219 let seq_marked = SeqMarked::new(5, Marked::Normal("data"));
220 let seq_marked_copy = seq_marked;
221 assert_eq!(seq_marked, seq_marked_copy);
222 }
223
224 #[test]
225 fn test_new() {
226 let seq_marked = SeqMarked::new(5, Marked::Normal("data"));
227 assert_eq!(seq_marked.seq, 5);
228 assert_eq!(seq_marked.marked, Marked::Normal("data"));
229 }
230
231 #[test]
232 fn test_map() -> anyhow::Result<()> {
233 let a = norm(1, 1u64);
234 assert_eq!(norm(1, 2u32), a.map(|x| (x * 2) as u32));
235
236 let a = ts::<u64>(1);
237 assert_eq!(ts::<u32>(1), a.map(|x| (x * 2) as u32));
238
239 Ok(())
240 }
241
242 #[test]
243 fn test_as_ref() -> anyhow::Result<()> {
244 let a = norm(1, 1u64);
245 assert_eq!(norm(1, &1u64), a.as_ref());
246
247 let a = ts::<u64>(1);
248 assert_eq!(ts::<&u64>(1), a.as_ref());
249
250 Ok(())
251 }
252
253 #[test]
254 fn test_order_key() -> anyhow::Result<()> {
255 assert!(norm(1, 1u64).order_key() == norm(1, 1u64).order_key());
256 assert!(norm(1, 2u64).order_key() == norm(1, 1u64).order_key());
257 assert!(norm(2, 2u64).order_key() > norm(1, 1u64).order_key());
258
259 assert!(ts::<u64>(1).order_key() > norm(1, 1u64).order_key());
260 assert!(ts::<u64>(2).order_key() > norm(1, 1u64).order_key());
261
262 assert!(ts::<u64>(2).order_key() > ts::<u64>(1).order_key());
263 assert!(ts::<u64>(1).order_key() == ts::<u64>(1).order_key());
264
265 Ok(())
266 }
267
268 #[test]
269 fn test_partial_ord() -> anyhow::Result<()> {
270 fn pcmp<D: PartialOrd>(a: &SeqMarked<D>, b: &SeqMarked<D>) -> Option<Ordering> {
271 PartialOrd::partial_cmp(a, b)
272 }
273
274 assert_eq!(Some(Greater), pcmp(&norm(2, 2u64), &norm(1, 2u64)));
277 assert_eq!(Some(Equal), pcmp(&norm(2, 2u64), &norm(2, 2u64)));
278 assert_eq!(Some(Less), pcmp(&norm(2, 2u64), &norm(3, 2u64)));
279
280 assert_eq!(Some(Greater), pcmp(&norm(2, 2u64), &norm(2, 1u64)));
283 assert_eq!(Some(Equal), pcmp(&norm(2, 2u64), &norm(2, 2u64)));
284 assert_eq!(Some(Less), pcmp(&norm(2, 2u64), &norm(2, 3u64)));
285
286 assert_eq!(Some(Greater), pcmp(&norm(2, 2u64), &ts(1)));
289 assert_eq!(
290 Some(Less),
291 pcmp(&norm(2, 2u64), &ts(2)),
292 "tombstone is greater than a normal with the same seq"
293 );
294 assert_eq!(Some(Less), pcmp(&norm(2, 2u64), &ts(3)));
295
296 assert_eq!(Some(Less), pcmp(&ts(1), &norm(2, 2u64)));
299 assert_eq!(
300 Some(Greater),
301 pcmp(&ts(2), &norm(2, 2u64)),
302 "tombstone is greater than a normal with the same seq"
303 );
304 assert_eq!(Some(Greater), pcmp(&ts(3), &norm(2, 2u64)));
305
306 assert_eq!(Some(Greater), pcmp(&ts::<()>(2), &ts(1)));
309 assert_eq!(Some(Equal), pcmp(&ts::<()>(2), &ts(2)));
310 assert_eq!(Some(Less), pcmp(&ts::<()>(2), &ts(3)));
311 Ok(())
312 }
313
314 #[test]
315 fn test_ord_operator() -> anyhow::Result<()> {
316 assert!(norm(2, 2u64) > norm(1, 2u64));
319 assert!(norm(2, 2u64) >= norm(1, 2u64));
320 assert!(norm(2, 2u64) == norm(2, 2u64));
321 assert!(norm(2, 2u64) <= norm(3, 2u64));
322 assert!(norm(2, 2u64) < norm(3, 2u64));
323
324 assert!(norm(2, 2u64) > norm(2, 1u64));
327 assert!(norm(2, 2u64) >= norm(2, 1u64));
328 assert!(norm(2, 2u64) == norm(2, 2u64));
329 assert!(norm(2, 2u64) <= norm(2, 3u64));
330 assert!(norm(2, 2u64) < norm(2, 3u64));
331
332 assert!(norm(2, 2u64) > ts(1));
335 assert!(norm(2, 2u64) >= ts(1));
336 assert!(
337 norm(2, 2u64) < ts(2),
338 "tombstone is greater than a normal with the same seq"
339 );
340 assert!(
341 norm(2, 2u64) <= ts(2),
342 "tombstone is greater than a normal with the same seq"
343 );
344 assert!(norm(2, 2u64) < ts(3));
345 assert!(norm(2, 2u64) <= ts(3));
346
347 assert!(ts(1) < norm(2, 2u64));
350 assert!(ts(1) <= norm(2, 2u64));
351 assert!(
352 ts(2) > norm(2, 2u64),
353 "tombstone is greater than a normal with the same seq"
354 );
355 assert!(
356 ts(2) >= norm(2, 2u64),
357 "tombstone is greater than a normal with the same seq"
358 );
359 assert!(ts(3) > norm(2, 2u64));
360 assert!(ts(3) >= norm(2, 2u64));
361
362 assert!(ts::<()>(2) > ts(1));
365 assert!(ts::<()>(2) >= ts(1));
366 assert!(ts::<()>(2) >= ts(2));
367 assert!(ts::<()>(2) == ts(2));
368 assert!(ts::<()>(2) <= ts(2));
369 assert!(ts::<()>(2) <= ts(3));
370 assert!(ts::<()>(2) < ts(3));
371
372 Ok(())
373 }
374
375 #[test]
376 fn test_new_absent() {
377 let absent = SeqMarked::<u64>::new_not_found();
378 assert_eq!(absent.seq, 0);
379 assert!(absent.is_tombstone());
380 }
381
382 #[test]
383 fn test_max() {
384 assert_eq!(
385 SeqMarked::<u64>::new_normal(2, 1),
386 SeqMarked::<u64>::max(
387 SeqMarked::<u64>::new_normal(1, 1),
388 SeqMarked::<u64>::new_normal(2, 1)
389 )
390 );
391 assert_eq!(
392 SeqMarked::<u64>::new_normal(2, 1),
393 SeqMarked::<u64>::max(
394 SeqMarked::<u64>::new_normal(1, 2),
395 SeqMarked::<u64>::new_normal(2, 1)
396 )
397 );
398 assert_eq!(
399 SeqMarked::<u64>::new_tombstone(2),
400 SeqMarked::<u64>::max(
401 SeqMarked::<u64>::new_normal(2, 1),
402 SeqMarked::<u64>::new_tombstone(2)
403 )
404 );
405 assert_eq!(
406 SeqMarked::<u64>::new_tombstone(2),
407 SeqMarked::<u64>::max(
408 SeqMarked::<u64>::new_tombstone(1),
409 SeqMarked::<u64>::new_tombstone(2)
410 )
411 );
412 }
413
414 #[test]
415 fn test_max_ref() {
416 let m1 = SeqMarked::new_normal(1, 2);
417 let m2 = SeqMarked::new_normal(3, 2);
418 let m3 = SeqMarked::new_tombstone(2);
419
420 assert_eq!(SeqMarked::max_ref(&m1, &m2), &m2);
421 assert_eq!(SeqMarked::max_ref(&m1, &m3), &m3);
422 assert_eq!(SeqMarked::max_ref(&m2, &m3), &m2);
423
424 assert_eq!(SeqMarked::max_ref(&m1, &m1), &m1);
425 assert_eq!(SeqMarked::max_ref(&m2, &m2), &m2);
426 assert_eq!(SeqMarked::max_ref(&m3, &m3), &m3);
427 }
428
429 #[test]
430 fn test_is_not_found() {
431 assert!(SeqMarked::<u64>::new_not_found().is_not_found());
432 assert!(SeqMarked::<u64>::new_tombstone(0).is_not_found());
433 assert!(!SeqMarked::<u64>::new_tombstone(1).is_not_found());
434 assert!(!SeqMarked::<u64>::new_normal(1, 1).is_not_found());
435 }
436
437 #[test]
438 fn test_into_parts() {
439 let seq_marked = SeqMarked::new_normal(5, "data");
440 let (seq, marked) = seq_marked.into_parts();
441 assert_eq!(seq, 5);
442 assert_eq!(marked, Marked::Normal("data"));
443 }
444
445 #[test]
446 fn test_internal_seq() {
447 let seq_marked = SeqMarked::new_normal(5, "data");
448 assert_eq!(seq_marked.internal_seq(), 5);
449
450 let seq_marked_tombstone = SeqMarked::<u64>::new_tombstone(10);
451 assert_eq!(seq_marked_tombstone.internal_seq(), 10);
452 }
453
454 #[test]
455 fn test_user_seq() {
456 let seq_marked = SeqMarked::new_normal(5, "data");
457 assert_eq!(seq_marked.user_seq(), 5);
458
459 let seq_marked_tombstone = SeqMarked::<u64>::new_tombstone(10);
460 assert_eq!(seq_marked_tombstone.user_seq(), 0);
461 }
462
463 #[test]
464 fn test_display_with_debug() {
465 let seq_marked = SeqMarked::new_normal(5, "data");
466 assert_eq!(
467 format!("{}", seq_marked.display_with_debug()),
468 "{seq: 5, (\"data\")}"
469 );
470 }
471
472 #[test]
473 fn test_display_with_debug_tombstone() {
474 let seq_marked = SeqMarked::<u64>::new_tombstone(5);
475 assert_eq!(
476 format!("{}", seq_marked.display_with_debug()),
477 "{seq: 5, TOMBSTONE}"
478 );
479 }
480}
481
482#[cfg(test)]
483#[cfg(feature = "seq-marked-bincode")]
484mod tests_bincode {
485
486 use super::*;
487 use crate::testing::bincode_config;
488 use crate::testing::test_bincode_decode;
489
490 #[test]
491 fn test_marked_bincode() {
492 let a = SeqMarked::new_normal(5, 1u64);
493 let encoded = bincode::encode_to_vec(&a, bincode_config()).unwrap();
494 let (decoded, n): (SeqMarked<u64>, usize) =
495 bincode::decode_from_slice(&encoded, bincode_config()).unwrap();
496 assert_eq!(n, 3);
497 assert_eq!(a, decoded);
498 }
499
500 #[test]
501 fn test_marked_bincode_decode_v010() -> anyhow::Result<()> {
502 let value = SeqMarked::new_normal(5, 1u64);
503 let encoded = vec![5, 0, 1];
504
505 test_bincode_decode(&encoded, &value)?;
506
507 let value = SeqMarked::<u64>::new_tombstone(6);
508 let encoded = vec![6, 1];
509
510 test_bincode_decode(&encoded, &value)?;
511 Ok(())
512 }
513}
514
515#[cfg(test)]
516#[cfg(feature = "seq-marked-serde")]
517mod tests_serde {
518 use super::*;
519 use crate::testing::test_serde_decode;
520
521 #[test]
522 fn test_marked_serde() {
523 let a = SeqMarked::new_normal(5, 1u64);
524 let encoded = serde_json::to_string(&a).unwrap();
525 let decoded: SeqMarked<u64> = serde_json::from_str(&encoded).unwrap();
526 assert_eq!(a, decoded);
527 }
528
529 #[test]
530 fn test_marked_serde_decode_v010() -> anyhow::Result<()> {
531 let value = SeqMarked::new_normal(5, 1u64);
532 let encoded = r#"{"seq":5,"marked":{"Normal":1}}"#;
533
534 test_serde_decode(encoded, &value)?;
535
536 let value = SeqMarked::<u64>::new_tombstone(6);
537 let encoded = r#"{"seq":6,"marked":"TombStone"}"#;
538
539 test_serde_decode(encoded, &value)?;
540 Ok(())
541 }
542}