Skip to main content

yugendb_core/
value.rs

1//! Stored byte value and metadata types.
2
3use bytes::Bytes;
4use chrono::{DateTime, Utc};
5
6/// Opaque serialised value bytes.
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct ValueBytes(Bytes);
9
10impl ValueBytes {
11    /// Creates value bytes from any byte-like input.
12    #[must_use]
13    pub fn new(bytes: impl Into<Bytes>) -> Self {
14        Self(bytes.into())
15    }
16
17    /// Returns the bytes as a slice.
18    #[must_use]
19    pub fn as_slice(&self) -> &[u8] {
20        &self.0
21    }
22
23    /// Returns the number of bytes.
24    #[must_use]
25    pub fn len(&self) -> usize {
26        self.0.len()
27    }
28
29    /// Returns true when there are no bytes.
30    #[must_use]
31    pub fn is_empty(&self) -> bool {
32        self.0.is_empty()
33    }
34
35    /// Converts into the inner bytes value.
36    #[must_use]
37    pub fn into_inner(self) -> Bytes {
38        self.0
39    }
40}
41
42impl From<Vec<u8>> for ValueBytes {
43    fn from(value: Vec<u8>) -> Self {
44        Self::new(value)
45    }
46}
47
48impl From<Bytes> for ValueBytes {
49    fn from(value: Bytes) -> Self {
50        Self::new(value)
51    }
52}
53
54impl AsRef<[u8]> for ValueBytes {
55    fn as_ref(&self) -> &[u8] {
56        self.as_slice()
57    }
58}
59
60/// Metadata stored alongside a serialised value.
61#[derive(Debug, Clone, PartialEq, Eq)]
62pub struct ValueMetadata {
63    /// Codec name used to serialise the value.
64    pub codec: String,
65    /// Creation timestamp in UTC.
66    pub created_at: DateTime<Utc>,
67    /// Last update timestamp in UTC.
68    pub updated_at: DateTime<Utc>,
69    /// Expiry timestamp in UTC, when TTL is used.
70    pub expires_at: Option<DateTime<Utc>>,
71}
72
73impl ValueMetadata {
74    /// Creates metadata using the same timestamp for creation and update.
75    #[must_use]
76    pub fn new(
77        codec: impl Into<String>,
78        now: DateTime<Utc>,
79        expires_at: Option<DateTime<Utc>>,
80    ) -> Self {
81        Self {
82            codec: codec.into(),
83            created_at: now,
84            updated_at: now,
85            expires_at,
86        }
87    }
88
89    /// Returns true when the metadata expiry time has passed.
90    #[must_use]
91    pub fn is_expired_at(&self, now: DateTime<Utc>) -> bool {
92        self.expires_at.is_some_and(|expires_at| expires_at <= now)
93    }
94}
95
96/// A serialised value and its metadata.
97#[derive(Debug, Clone, PartialEq, Eq)]
98pub struct StoredValue {
99    /// Serialised value bytes.
100    pub bytes: ValueBytes,
101    /// Stored value metadata.
102    pub metadata: ValueMetadata,
103}
104
105impl StoredValue {
106    /// Creates a stored value.
107    #[must_use]
108    pub fn new(bytes: ValueBytes, metadata: ValueMetadata) -> Self {
109        Self { bytes, metadata }
110    }
111
112    /// Returns true when the value has expired at the current time.
113    #[must_use]
114    pub fn is_expired(&self) -> bool {
115        self.metadata.is_expired_at(Utc::now())
116    }
117}