tuwunel_database/keyval.rs
1//! Key and value byte aliases plus database codec adapters.
2//!
3//! The aliases distinguish keys from values while sharing compact storage; raw
4//! aliases default to borrowed byte slices, while buffer aliases provide inline
5//! capacity for common payload sizes. Serialization helpers encode typed
6//! components with the database record codec, and projection helpers consume
7//! pairs to return one component without cloning or reserializing it.
8
9use serde::{Deserialize, Serialize};
10use tuwunel_core::{Result, smallvec::SmallVec};
11
12use crate::{de, ser};
13
14/// Database key and value pair, borrowing raw byte slices by default.
15///
16/// `K` and `V` can replace the raw defaults with decoded or owned types. The
17/// lifetime tracks borrowed forms and does not affect owned substitutions.
18pub type KeyVal<'a, K = &'a Slice, V = &'a Slice> = (Key<'a, K>, Val<'a, V>);
19
20/// Database key, borrowing a raw byte slice by default.
21///
22/// Substitute `T` for a decoded or owned key type. The alias adds no runtime
23/// wrapper.
24pub type Key<'a, T = &'a Slice> = T;
25
26/// Database value, borrowing a raw byte slice by default.
27///
28/// Substitute `T` for a decoded or owned value type. The alias adds no runtime
29/// wrapper.
30pub type Val<'a, T = &'a Slice> = T;
31
32/// Default inline-backed buffer for a serialized key.
33///
34/// This aliases [`KeyBuffer`] with [`KEY_STACK_CAP`] bytes of inline storage.
35/// Longer keys remain valid and spill to the heap.
36pub type KeyBuf = KeyBuffer;
37
38/// Default inline-backed buffer for a serialized value.
39///
40/// This aliases [`ValBuffer`] with [`VAL_STACK_CAP`] bytes of inline storage.
41/// Longer values remain valid and spill to the heap.
42pub type ValBuf = ValBuffer;
43
44/// Inline-backed key buffer with a configurable byte capacity.
45///
46/// The buffer provides `CAP` bytes of inline storage. Operations requiring
47/// greater capacity spill it to the heap. [`KeyBuf`] selects the crate's
48/// default key capacity.
49pub type KeyBuffer<const CAP: usize = KEY_STACK_CAP> = Buffer<CAP>;
50
51/// Inline-backed value buffer with a configurable byte capacity.
52///
53/// The buffer provides `CAP` bytes of inline storage. Operations requiring
54/// greater capacity spill it to the heap. [`ValBuf`] selects the crate's
55/// default value capacity.
56pub type ValBuffer<const CAP: usize = VAL_STACK_CAP> = Buffer<CAP>;
57
58/// Inline-backed byte buffer used by serialized keys and values.
59///
60/// The const parameter sets the number of bytes stored inline by [`SmallVec`].
61/// Capacity growth beyond that budget uses heap storage without truncating the
62/// payload.
63pub type Buffer<const CAP: usize = DEF_STACK_CAP> = SmallVec<[Byte; CAP]>;
64
65/// Unsized byte slice used by raw database APIs.
66///
67/// This aliases `[u8]` so borrowed keys and values share one canonical
68/// spelling. The alias itself carries no encoding guarantee.
69pub type Slice = [Byte];
70
71/// Byte element used by raw database slices and buffers.
72///
73/// This aliases `u8` and gives the related storage aliases a common element
74/// name. It carries no additional representation.
75pub type Byte = u8;
76
77/// Default inline byte capacity for serialized keys.
78///
79/// [`KeyBuffer`] uses this value when no capacity is supplied. Keys exceeding
80/// the budget spill to the heap rather than being truncated.
81pub const KEY_STACK_CAP: usize = 128 - 16;
82
83/// Default inline byte capacity for serialized values.
84///
85/// [`ValBuffer`] uses this value when no capacity is supplied. Values exceeding
86/// the budget spill to the heap rather than being truncated.
87pub const VAL_STACK_CAP: usize = 512 - 16;
88
89/// Default inline byte capacity for a generic [`Buffer`].
90///
91/// The generic default matches [`KEY_STACK_CAP`]. Key and value aliases may
92/// select different capacities explicitly.
93pub const DEF_STACK_CAP: usize = KEY_STACK_CAP;
94
95/// Serializes a database key into an inline-backed key buffer.
96///
97/// The compact database record codec determines the byte representation. The
98/// buffer spills to the heap if the encoded key exceeds [`KEY_STACK_CAP`].
99///
100/// # Panics
101///
102/// Panics if `T` requests a Serde data-model operation unsupported by the
103/// database codec. Debug builds also panic when record-layout invariants are
104/// violated or when a directly wrapped
105/// `Json<Box<serde_json::value::RawValue>>` is serialized.
106#[inline]
107pub fn serialize_key<T>(val: T) -> Result<KeyBuf>
108where
109 T: Serialize,
110{
111 ser::serialize_to::<KeyBuf, _>(val)
112}
113
114/// Serializes a database value into an inline-backed value buffer.
115///
116/// The compact database record codec determines the byte representation. The
117/// buffer spills to the heap if the encoded value exceeds [`VAL_STACK_CAP`].
118///
119/// # Panics
120///
121/// Panics if `T` requests a Serde data-model operation unsupported by the
122/// database codec. Debug builds also panic when record-layout invariants are
123/// violated or when a directly wrapped
124/// `Json<Box<serde_json::value::RawValue>>` is serialized.
125#[inline]
126pub fn serialize_val<T>(val: T) -> Result<ValBuf>
127where
128 T: Serialize,
129{
130 ser::serialize_to::<ValBuf, _>(val)
131}
132
133/// Deserializes both components and treats any input or codec error as fatal.
134///
135/// The returned key and value may borrow from the original raw pair. Prefer the
136/// fallible helper when a caller can propagate decoding failure.
137///
138/// # Panics
139///
140/// Panics if the input is an error or either component cannot be deserialized.
141#[inline]
142pub(crate) fn _expect_deserialize<'a, K, V>(kv: Result<KeyVal<'a>>) -> KeyVal<'a, K, V>
143where
144 K: Deserialize<'a>,
145 V: Deserialize<'a>,
146{
147 result_deserialize(kv).expect("failed to deserialize result key/val")
148}
149
150/// Deserializes a key and treats any input or codec error as fatal.
151///
152/// The returned key may borrow from the original raw bytes. Prefer the fallible
153/// helper when a caller can propagate decoding failure.
154///
155/// # Panics
156///
157/// Panics if the input is an error or the key cannot be deserialized.
158#[inline]
159pub(crate) fn _expect_deserialize_key<'a, K>(key: Result<Key<'a>>) -> Key<'a, K>
160where
161 K: Deserialize<'a>,
162{
163 result_deserialize_key(key).expect("failed to deserialize result key")
164}
165
166#[inline]
167pub(crate) fn result_deserialize<'a, K, V>(kv: Result<KeyVal<'a>>) -> Result<KeyVal<'a, K, V>>
168where
169 K: Deserialize<'a>,
170 V: Deserialize<'a>,
171{
172 deserialize(kv?)
173}
174
175#[inline]
176pub(crate) fn result_deserialize_key<'a, K>(key: Result<Key<'a>>) -> Result<Key<'a, K>>
177where
178 K: Deserialize<'a>,
179{
180 deserialize_key(key?)
181}
182
183#[inline]
184pub(crate) fn deserialize<'a, K, V>(kv: KeyVal<'a>) -> Result<KeyVal<'a, K, V>>
185where
186 K: Deserialize<'a>,
187 V: Deserialize<'a>,
188{
189 Ok((deserialize_key::<K>(kv.0)?, deserialize_val::<V>(kv.1)?))
190}
191
192#[inline]
193pub(crate) fn deserialize_key<'a, K>(key: Key<'a>) -> Result<Key<'a, K>>
194where
195 K: Deserialize<'a>,
196{
197 de::from_slice::<K>(key)
198}
199
200#[inline]
201pub(crate) fn deserialize_val<'a, V>(val: Val<'a>) -> Result<Val<'a, V>>
202where
203 V: Deserialize<'a>,
204{
205 de::from_slice::<V>(val)
206}
207
208/// Returns the key component of a database pair.
209///
210/// The pair is consumed and its value component is dropped. No serialization or
211/// allocation is performed by this projection.
212#[inline]
213pub fn key<K, V>(kv: KeyVal<'_, K, V>) -> Key<'_, K> { kv.0 }
214
215/// Returns the value component of a database pair.
216///
217/// The pair is consumed and its key component is dropped. No serialization or
218/// allocation is performed by this projection.
219#[inline]
220pub fn val<K, V>(kv: KeyVal<'_, K, V>) -> Val<'_, V> { kv.1 }