Skip to main content

dodb_core/
revision.rs

1use crate::{Lsn, Revision};
2
3/// The committed state of one logical document key.
4///
5/// `Missing` is intentionally not represented as `Option`: a deleted key
6/// retains the LSN of its deletion so optimistic validation can detect ABA.
7#[derive(Clone, Debug, Eq, PartialEq)]
8pub enum RevisionState {
9    Present { value: Vec<u8>, revision: Revision },
10    Missing { revision: Revision },
11}
12
13/// The committed presence and identity of one logical document key without
14/// materializing its value.
15#[derive(Clone, Copy, Debug, Eq, PartialEq)]
16pub enum ObservedState {
17    Present { revision: Revision },
18    Missing { revision: Revision },
19}
20
21impl ObservedState {
22    pub const fn present(revision: Revision) -> Self {
23        Self::Present { revision }
24    }
25
26    pub const fn missing(revision: Revision) -> Self {
27        Self::Missing { revision }
28    }
29
30    pub const fn revision(self) -> Revision {
31        match self {
32            Self::Present { revision } | Self::Missing { revision } => revision,
33        }
34    }
35
36    pub const fn is_missing(self) -> bool {
37        matches!(self, Self::Missing { .. })
38    }
39}
40
41impl RevisionState {
42    pub fn present(value: impl Into<Vec<u8>>, revision: Revision) -> Self {
43        Self::Present {
44            value: value.into(),
45            revision,
46        }
47    }
48
49    pub fn missing(revision: Revision) -> Self {
50        Self::Missing { revision }
51    }
52
53    pub const fn revision(&self) -> Revision {
54        match self {
55            Self::Present { revision, .. } | Self::Missing { revision } => *revision,
56        }
57    }
58
59    pub fn value(&self) -> Option<&[u8]> {
60        match self {
61            Self::Present { value, .. } => Some(value),
62            Self::Missing { .. } => None,
63        }
64    }
65
66    pub fn is_missing(&self) -> bool {
67        matches!(self, Self::Missing { .. })
68    }
69
70    pub const fn observed(&self) -> ObservedState {
71        match self {
72            Self::Present { revision, .. } => ObservedState::Present {
73                revision: *revision,
74            },
75            Self::Missing { revision } => ObservedState::Missing {
76                revision: *revision,
77            },
78        }
79    }
80}
81
82impl From<Lsn> for Revision {
83    fn from(lsn: Lsn) -> Self {
84        Self::new(lsn.get())
85    }
86}