Skip to main content

icydb_core/db/data/persisted_row/
codec.rs

1//! Module: db::data::persisted_row::codec
2//! Defines the persisted scalar row-slot encoding and borrowed decoding helpers
3//! used by runtime row access.
4
5use crate::{
6    db::data::{
7        decode_account, decode_blob_field_by_kind_bytes, decode_bool_field_by_kind_bytes,
8        decode_date_field_by_kind_bytes, decode_decimal, decode_decimal_field_by_kind_bytes,
9        decode_duration_field_by_kind_bytes, decode_float32_field_by_kind_bytes,
10        decode_float64_field_by_kind_bytes, decode_int, decode_int_big_field_by_kind_bytes,
11        decode_int128, decode_int128_field_by_kind_bytes, decode_list_field_items,
12        decode_list_item, decode_map_entry, decode_map_field_entries, decode_nat, decode_nat128,
13        decode_nat128_field_by_kind_bytes, decode_optional_storage_key_field_bytes,
14        decode_storage_key_binary_value_bytes, decode_structural_field_by_kind_bytes,
15        decode_structural_value_storage_blob_bytes, decode_structural_value_storage_bool_bytes,
16        decode_structural_value_storage_bytes, decode_structural_value_storage_date_bytes,
17        decode_structural_value_storage_duration_bytes,
18        decode_structural_value_storage_float32_bytes,
19        decode_structural_value_storage_float64_bytes, decode_structural_value_storage_i64_bytes,
20        decode_structural_value_storage_principal_bytes,
21        decode_structural_value_storage_subaccount_bytes,
22        decode_structural_value_storage_timestamp_bytes, decode_structural_value_storage_u64_bytes,
23        decode_structural_value_storage_ulid_bytes, decode_structural_value_storage_unit_bytes,
24        decode_text, decode_text_field_by_kind_bytes, decode_uint_big_field_by_kind_bytes,
25        encode_account, encode_blob_field_by_kind_bytes, encode_bool_field_by_kind_bytes,
26        encode_date_field_by_kind_bytes, encode_decimal, encode_decimal_field_by_kind_bytes,
27        encode_duration_field_by_kind_bytes, encode_float32_field_by_kind_bytes,
28        encode_float64_field_by_kind_bytes, encode_int, encode_int_big_field_by_kind_bytes,
29        encode_int128, encode_int128_field_by_kind_bytes, encode_list_field_items,
30        encode_list_item, encode_map_entry, encode_map_field_entries, encode_nat, encode_nat128,
31        encode_nat128_field_by_kind_bytes, encode_storage_key_binary_value_bytes,
32        encode_storage_key_field_bytes, encode_structural_field_by_kind_bytes,
33        encode_structural_value_storage_blob_bytes, encode_structural_value_storage_bool_bytes,
34        encode_structural_value_storage_bytes, encode_structural_value_storage_date_bytes,
35        encode_structural_value_storage_duration_bytes,
36        encode_structural_value_storage_float32_bytes,
37        encode_structural_value_storage_float64_bytes, encode_structural_value_storage_i64_bytes,
38        encode_structural_value_storage_null_bytes,
39        encode_structural_value_storage_principal_bytes,
40        encode_structural_value_storage_subaccount_bytes,
41        encode_structural_value_storage_timestamp_bytes, encode_structural_value_storage_u64_bytes,
42        encode_structural_value_storage_ulid_bytes, encode_structural_value_storage_unit_bytes,
43        encode_text, encode_text_field_by_kind_bytes, encode_uint_big_field_by_kind_bytes,
44        structural_value_storage_bytes_are_null, supports_storage_key_binary_kind,
45    },
46    error::InternalError,
47    model::field::{FieldKind, ScalarCodec},
48    traits::{
49        Collection, PersistedByKindCodec, PersistedFieldMetaCodec, PersistedStructuredFieldCodec,
50    },
51    types::{
52        Account, Blob, Date, Decimal, Duration, Float32, Float64, Int, Int128, Nat, Nat128,
53        Principal, Subaccount, Timestamp, Ulid, Unit,
54    },
55    value::{StorageKey, Value},
56};
57use std::collections::{BTreeMap, BTreeSet};
58use std::str;
59
60const SCALAR_SLOT_PREFIX: u8 = 0xFF;
61const SCALAR_SLOT_TAG_NULL: u8 = 0;
62const SCALAR_SLOT_TAG_VALUE: u8 = 1;
63
64const SCALAR_BOOL_PAYLOAD_LEN: usize = 1;
65const SCALAR_WORD32_PAYLOAD_LEN: usize = 4;
66const SCALAR_WORD64_PAYLOAD_LEN: usize = 8;
67const SCALAR_ULID_PAYLOAD_LEN: usize = 16;
68const SCALAR_SUBACCOUNT_PAYLOAD_LEN: usize = 32;
69
70const SCALAR_BOOL_FALSE_TAG: u8 = 0;
71const SCALAR_BOOL_TRUE_TAG: u8 = 1;
72
73///
74/// ScalarValueRef
75///
76/// ScalarValueRef is the borrowed-or-copy scalar payload view returned by the
77/// slot-reader fast path.
78/// It preserves cheap references for text/blob payloads while keeping fixed
79/// width scalar wrappers as copy values.
80///
81
82#[derive(Clone, Copy, Debug)]
83pub enum ScalarValueRef<'a> {
84    Blob(&'a [u8]),
85    Bool(bool),
86    Date(Date),
87    Duration(Duration),
88    Float32(Float32),
89    Float64(Float64),
90    Int(i64),
91    Principal(Principal),
92    Subaccount(Subaccount),
93    Text(&'a str),
94    Timestamp(Timestamp),
95    Uint(u64),
96    Ulid(Ulid),
97    Unit,
98}
99
100impl ScalarValueRef<'_> {
101    /// Materialize this scalar view into the runtime `Value` enum.
102    #[must_use]
103    pub fn into_value(self) -> Value {
104        match self {
105            Self::Blob(value) => Value::Blob(value.to_vec()),
106            Self::Bool(value) => Value::Bool(value),
107            Self::Date(value) => Value::Date(value),
108            Self::Duration(value) => Value::Duration(value),
109            Self::Float32(value) => Value::Float32(value),
110            Self::Float64(value) => Value::Float64(value),
111            Self::Int(value) => Value::Int(value),
112            Self::Principal(value) => Value::Principal(value),
113            Self::Subaccount(value) => Value::Subaccount(value),
114            Self::Text(value) => Value::Text(value.to_owned()),
115            Self::Timestamp(value) => Value::Timestamp(value),
116            Self::Uint(value) => Value::Uint(value),
117            Self::Ulid(value) => Value::Ulid(value),
118            Self::Unit => Value::Unit,
119        }
120    }
121}
122
123///
124/// ScalarSlotValueRef
125///
126/// ScalarSlotValueRef preserves the distinction between a missing slot and an
127/// explicitly persisted `NULL` scalar payload.
128/// The outer `Option` from `SlotReader::get_scalar` therefore still means
129/// "slot absent".
130///
131
132#[derive(Clone, Copy, Debug)]
133pub enum ScalarSlotValueRef<'a> {
134    Null,
135    Value(ScalarValueRef<'a>),
136}
137
138///
139/// PersistedScalar
140///
141/// PersistedScalar defines the canonical binary payload codec for one scalar
142/// leaf type.
143/// Derive-generated persisted-row materializers and writers use this trait to
144/// avoid routing scalar fields back through a generic structural envelope.
145///
146
147pub trait PersistedScalar: Sized {
148    /// Canonical scalar codec identifier used by schema/runtime metadata.
149    const CODEC: ScalarCodec;
150
151    /// Encode this scalar value into its codec-specific payload bytes.
152    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError>;
153
154    /// Decode this scalar value from its codec-specific payload bytes.
155    fn decode_scalar_payload(bytes: &[u8], field_name: &'static str)
156    -> Result<Self, InternalError>;
157}
158
159/// Encode one persisted slot payload using the stricter schema-owned `ByKind`
160/// storage contract.
161pub fn encode_persisted_slot_payload_by_kind<T>(
162    value: &T,
163    kind: FieldKind,
164    field_name: &'static str,
165) -> Result<Vec<u8>, InternalError>
166where
167    T: PersistedByKindCodec,
168{
169    value.encode_persisted_slot_payload_by_kind(kind, field_name)
170}
171
172/// Encode one persisted scalar slot payload using the canonical scalar envelope.
173pub fn encode_persisted_scalar_slot_payload<T>(
174    value: &T,
175    field_name: &'static str,
176) -> Result<Vec<u8>, InternalError>
177where
178    T: PersistedScalar,
179{
180    let payload = value.encode_scalar_payload()?;
181    let mut encoded = Vec::with_capacity(payload.len() + 2);
182    encoded.push(SCALAR_SLOT_PREFIX);
183    encoded.push(SCALAR_SLOT_TAG_VALUE);
184    encoded.extend_from_slice(&payload);
185
186    if encoded.len() < 2 {
187        return Err(InternalError::persisted_row_field_encode_failed(
188            field_name,
189            "scalar payload envelope underflow",
190        ));
191    }
192
193    Ok(encoded)
194}
195
196/// Encode one optional persisted scalar slot payload preserving explicit `NULL`.
197pub fn encode_persisted_option_scalar_slot_payload<T>(
198    value: &Option<T>,
199    field_name: &'static str,
200) -> Result<Vec<u8>, InternalError>
201where
202    T: PersistedScalar,
203{
204    match value {
205        Some(value) => encode_persisted_scalar_slot_payload(value, field_name),
206        None => Ok(vec![SCALAR_SLOT_PREFIX, SCALAR_SLOT_TAG_NULL]),
207    }
208}
209
210// Decode one `ByKind` structural persisted payload, preserving the explicit
211// null sentinel instead of forcing each wrapper to repeat the same branch.
212fn decode_persisted_structural_slot_payload_by_kind<T>(
213    bytes: &[u8],
214    kind: FieldKind,
215    field_name: &'static str,
216) -> Result<Option<T>, InternalError>
217where
218    T: PersistedByKindCodec,
219{
220    T::decode_persisted_option_slot_payload_by_kind(bytes, kind, field_name)
221}
222
223/// Decode one persisted slot payload using the stricter schema-owned `ByKind`
224/// storage contract.
225pub fn decode_persisted_slot_payload_by_kind<T>(
226    bytes: &[u8],
227    kind: FieldKind,
228    field_name: &'static str,
229) -> Result<T, InternalError>
230where
231    T: PersistedByKindCodec,
232{
233    decode_persisted_structural_slot_payload_by_kind(bytes, kind, field_name)?.ok_or_else(|| {
234        InternalError::persisted_row_field_decode_failed(
235            field_name,
236            "unexpected null for non-nullable field",
237        )
238    })
239}
240
241/// Decode one optional persisted slot payload preserving the explicit null
242/// sentinel under the stricter schema-owned `ByKind` storage contract.
243pub fn decode_persisted_option_slot_payload_by_kind<T>(
244    bytes: &[u8],
245    kind: FieldKind,
246    field_name: &'static str,
247) -> Result<Option<T>, InternalError>
248where
249    T: PersistedByKindCodec,
250{
251    decode_persisted_structural_slot_payload_by_kind(bytes, kind, field_name)
252}
253
254macro_rules! impl_persisted_by_kind_direct_leaf {
255    ($($ty:ty => { encode: $encode:expr, decode: $decode:expr }),* $(,)?) => {
256        $(
257            impl PersistedByKindCodec for $ty {
258                fn encode_persisted_slot_payload_by_kind(
259                    &self,
260                    kind: FieldKind,
261                    field_name: &'static str,
262                ) -> Result<Vec<u8>, InternalError> {
263                    ($encode)(self, kind, field_name)
264                }
265
266                fn decode_persisted_option_slot_payload_by_kind(
267                    bytes: &[u8],
268                    kind: FieldKind,
269                    field_name: &'static str,
270                ) -> Result<Option<Self>, InternalError> {
271                    ($decode)(bytes, kind, field_name)
272                }
273            }
274        )*
275    };
276}
277
278macro_rules! impl_persisted_by_kind_scalar_leaf {
279    ($($ty:ty => { encode: $encode:ident, decode: $decode:ident }),* $(,)?) => {
280        impl_persisted_by_kind_direct_leaf!(
281            $(
282                $ty => {
283                    encode: |value: &$ty, kind: FieldKind, field_name: &'static str| {
284                        $encode(*value, kind, field_name)
285                    },
286                    decode: |bytes: &[u8], kind: FieldKind, field_name: &'static str| {
287                        $decode(bytes, kind)
288                            .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))
289                    }
290                }
291            ),*
292        );
293    };
294}
295
296macro_rules! impl_persisted_by_kind_ref_leaf {
297    ($($ty:ty => { encode: $encode:ident, decode: $decode:ident }),* $(,)?) => {
298        impl_persisted_by_kind_direct_leaf!(
299            $(
300                $ty => {
301                    encode: |value: &$ty, kind: FieldKind, field_name: &'static str| {
302                        $encode(value, kind, field_name)
303                    },
304                    decode: |bytes: &[u8], kind: FieldKind, field_name: &'static str| {
305                        $decode(bytes, kind)
306                            .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))
307                    }
308                }
309            ),*
310        );
311    };
312}
313
314macro_rules! impl_persisted_by_kind_value_leaf {
315    ($($ty:ty => { encode: $encode:ident, decode: $decode:ident }),* $(,)?) => {
316        impl_persisted_by_kind_direct_leaf!(
317            $(
318                $ty => {
319                    encode: |value: &$ty, kind: FieldKind, field_name: &'static str| {
320                        $encode(*value, kind, field_name)
321                    },
322                    decode: |bytes: &[u8], kind: FieldKind, field_name: &'static str| {
323                        $decode(bytes, kind)
324                            .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))
325                    }
326                }
327            ),*
328        );
329    };
330}
331
332macro_rules! impl_persisted_by_kind_storage_int_leaf {
333    ($($ty:ty),* $(,)?) => {
334        impl_persisted_by_kind_direct_leaf!(
335            $(
336                $ty => {
337                    encode: |value: &$ty, kind: FieldKind, field_name: &'static str| {
338                        encode_storage_key_field_bytes(StorageKey::Int(i64::from(*value)), kind, field_name)
339                    },
340                    decode: |bytes: &[u8], kind: FieldKind, field_name: &'static str| {
341                        let Some(key) = decode_optional_storage_key_field_bytes(bytes, kind)
342                            .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))?
343                        else {
344                            return Ok(None);
345                        };
346
347                        let StorageKey::Int(value) = key else {
348                            return Err(InternalError::persisted_row_field_decode_failed(
349                                field_name,
350                                format!("field kind {kind:?} did not decode as storage int"),
351                            ));
352                        };
353
354                        <$ty>::try_from(value).map(Some).map_err(|_| {
355                            InternalError::persisted_row_field_decode_failed(
356                                field_name,
357                                format!("field kind {kind:?} did not decode as storage int"),
358                            )
359                        })
360                    }
361                }
362            ),*
363        );
364    };
365}
366
367macro_rules! impl_persisted_by_kind_storage_uint_leaf {
368    ($($ty:ty),* $(,)?) => {
369        impl_persisted_by_kind_direct_leaf!(
370            $(
371                $ty => {
372                    encode: |value: &$ty, kind: FieldKind, field_name: &'static str| {
373                        encode_storage_key_field_bytes(StorageKey::Uint(u64::from(*value)), kind, field_name)
374                    },
375                    decode: |bytes: &[u8], kind: FieldKind, field_name: &'static str| {
376                        let Some(key) = decode_optional_storage_key_field_bytes(bytes, kind)
377                            .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))?
378                        else {
379                            return Ok(None);
380                        };
381
382                        let StorageKey::Uint(value) = key else {
383                            return Err(InternalError::persisted_row_field_decode_failed(
384                                field_name,
385                                format!("field kind {kind:?} did not decode as storage uint"),
386                            ));
387                        };
388
389                        <$ty>::try_from(value).map(Some).map_err(|_| {
390                            InternalError::persisted_row_field_decode_failed(
391                                field_name,
392                                format!("field kind {kind:?} did not decode as storage uint"),
393                            )
394                        })
395                    }
396                }
397            ),*
398        );
399    };
400}
401
402macro_rules! impl_persisted_by_kind_storage_leaf {
403    ($($ty:ty => { variant: $variant:ident, label: $label:literal }),* $(,)?) => {
404        impl_persisted_by_kind_direct_leaf!(
405            $(
406                $ty => {
407                    encode: |value: &$ty, kind: FieldKind, field_name: &'static str| {
408                        encode_storage_key_field_bytes(StorageKey::$variant(*value), kind, field_name)
409                    },
410                    decode: |bytes: &[u8], kind: FieldKind, field_name: &'static str| {
411                        let Some(key) = decode_optional_storage_key_field_bytes(bytes, kind)
412                            .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))?
413                        else {
414                            return Ok(None);
415                        };
416
417                        match key {
418                            StorageKey::$variant(value) => Ok(Some(value)),
419                            _ => Err(InternalError::persisted_row_field_decode_failed(
420                                field_name,
421                                format!("field kind {kind:?} did not decode as {}", $label),
422                            )),
423                        }
424                    }
425                }
426            ),*
427        );
428    };
429}
430
431macro_rules! impl_persisted_by_kind_storage_unit_leaf {
432    ($ty:ty) => {
433        impl_persisted_by_kind_direct_leaf!(
434            $ty => {
435                encode: |_: &$ty, kind: FieldKind, field_name: &'static str| {
436                    encode_storage_key_field_bytes(StorageKey::Unit, kind, field_name)
437                },
438                decode: |bytes: &[u8], kind: FieldKind, field_name: &'static str| {
439                    let Some(key) = decode_optional_storage_key_field_bytes(bytes, kind)
440                        .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))?
441                    else {
442                        return Ok(None);
443                    };
444
445                    match key {
446                        StorageKey::Unit => Ok(Some(Unit)),
447                        _ => Err(InternalError::persisted_row_field_decode_failed(
448                            field_name,
449                            format!("field kind {kind:?} did not decode as storage unit"),
450                        )),
451                    }
452                }
453            }
454        );
455    };
456}
457
458impl_persisted_by_kind_scalar_leaf!(
459    bool => { encode: encode_bool_field_by_kind_bytes, decode: decode_bool_field_by_kind_bytes },
460    Float32 => { encode: encode_float32_field_by_kind_bytes, decode: decode_float32_field_by_kind_bytes },
461    Float64 => { encode: encode_float64_field_by_kind_bytes, decode: decode_float64_field_by_kind_bytes },
462    Int128 => { encode: encode_int128_field_by_kind_bytes, decode: decode_int128_field_by_kind_bytes },
463    Nat128 => { encode: encode_nat128_field_by_kind_bytes, decode: decode_nat128_field_by_kind_bytes }
464);
465
466impl_persisted_by_kind_ref_leaf!(
467    String => { encode: encode_text_field_by_kind_bytes, decode: decode_text_field_by_kind_bytes },
468    Blob => { encode: encode_blob_field_by_kind_bytes, decode: decode_blob_field_by_kind_bytes },
469    Int => { encode: encode_int_big_field_by_kind_bytes, decode: decode_int_big_field_by_kind_bytes },
470    Nat => { encode: encode_uint_big_field_by_kind_bytes, decode: decode_uint_big_field_by_kind_bytes }
471);
472
473impl_persisted_by_kind_value_leaf!(
474    Date => { encode: encode_date_field_by_kind_bytes, decode: decode_date_field_by_kind_bytes },
475    Decimal => { encode: encode_decimal_field_by_kind_bytes, decode: decode_decimal_field_by_kind_bytes },
476    Duration => { encode: encode_duration_field_by_kind_bytes, decode: decode_duration_field_by_kind_bytes }
477);
478
479impl_persisted_by_kind_storage_int_leaf!(i8, i16, i32, i64);
480impl_persisted_by_kind_storage_uint_leaf!(u8, u16, u32, u64);
481impl_persisted_by_kind_storage_leaf!(
482    Account => { variant: Account, label: "storage account" },
483    Timestamp => { variant: Timestamp, label: "storage timestamp" },
484    Principal => { variant: Principal, label: "storage principal" },
485    Subaccount => { variant: Subaccount, label: "storage subaccount" },
486    Ulid => { variant: Ulid, label: "storage ulid" }
487);
488impl_persisted_by_kind_storage_unit_leaf!(Unit);
489
490// Encode one explicit by-kind owner through the current field-kind structural
491// contract.
492fn encode_explicit_by_kind_value(
493    kind: FieldKind,
494    value: &Value,
495    field_name: &'static str,
496) -> Result<Vec<u8>, InternalError> {
497    if supports_storage_key_binary_kind(kind) {
498        return encode_storage_key_binary_value_bytes(kind, value, field_name)?.ok_or_else(|| {
499            InternalError::persisted_row_field_encode_failed(
500                field_name,
501                "storage-key binary lane rejected a supported field kind",
502            )
503        });
504    }
505
506    encode_structural_field_by_kind_bytes(kind, value, field_name)
507        .map_err(|err| InternalError::persisted_row_field_encode_failed(field_name, err))
508}
509
510// Decode one explicit by-kind owner through the current field-kind structural
511// contract.
512fn decode_explicit_by_kind_value(
513    bytes: &[u8],
514    kind: FieldKind,
515    field_name: &'static str,
516) -> Result<Option<Value>, InternalError> {
517    let value = if supports_storage_key_binary_kind(kind) {
518        decode_storage_key_binary_value_bytes(bytes, kind)
519            .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))?
520            .ok_or_else(|| {
521                InternalError::persisted_row_field_decode_failed(
522                    field_name,
523                    "storage-key binary lane rejected a supported field kind",
524                )
525            })?
526    } else {
527        decode_structural_field_by_kind_bytes(bytes, kind)
528            .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))?
529    };
530
531    if matches!(value, Value::Null) {
532        return Ok(None);
533    }
534
535    Ok(Some(value))
536}
537
538impl<T> PersistedByKindCodec for Box<T>
539where
540    T: PersistedByKindCodec,
541{
542    fn encode_persisted_slot_payload_by_kind(
543        &self,
544        kind: FieldKind,
545        field_name: &'static str,
546    ) -> Result<Vec<u8>, InternalError> {
547        self.as_ref()
548            .encode_persisted_slot_payload_by_kind(kind, field_name)
549    }
550
551    fn decode_persisted_option_slot_payload_by_kind(
552        bytes: &[u8],
553        kind: FieldKind,
554        field_name: &'static str,
555    ) -> Result<Option<Self>, InternalError> {
556        T::decode_persisted_option_slot_payload_by_kind(bytes, kind, field_name)
557            .map(|value| value.map(Self::new))
558    }
559}
560
561impl<T> PersistedByKindCodec for Option<T>
562where
563    T: PersistedByKindCodec,
564{
565    fn encode_persisted_slot_payload_by_kind(
566        &self,
567        kind: FieldKind,
568        field_name: &'static str,
569    ) -> Result<Vec<u8>, InternalError> {
570        match self {
571            Some(value) => value.encode_persisted_slot_payload_by_kind(kind, field_name),
572            None => encode_explicit_by_kind_value(kind, &Value::Null, field_name),
573        }
574    }
575
576    fn decode_persisted_option_slot_payload_by_kind(
577        bytes: &[u8],
578        kind: FieldKind,
579        field_name: &'static str,
580    ) -> Result<Option<Self>, InternalError> {
581        match decode_explicit_by_kind_value(bytes, kind, field_name)? {
582            None => Ok(Some(None)),
583            Some(_) => T::decode_persisted_option_slot_payload_by_kind(bytes, kind, field_name)
584                .map(|value| value.map(Some)),
585        }
586    }
587}
588
589// Encode one explicit by-kind wrapper owner through its value-surface
590// Decode one nested by-kind payload and require that it materializes a real
591// value rather than an incompatible null for this owner type.
592fn decode_required_nested_by_kind<T>(
593    bytes: &[u8],
594    kind: FieldKind,
595    field_name: &'static str,
596    label: &'static str,
597) -> Result<T, InternalError>
598where
599    T: PersistedByKindCodec,
600{
601    T::decode_persisted_option_slot_payload_by_kind(bytes, kind, field_name)?.ok_or_else(|| {
602        InternalError::persisted_row_field_decode_failed(
603            field_name,
604            format!(
605                "{label} payload did not decode as {}",
606                std::any::type_name::<T>()
607            ),
608        )
609    })
610}
611
612// Encode one collection wrapper through recursive by-kind item ownership
613// instead of re-entering the generic runtime `Value` bridge.
614fn encode_direct_by_kind_collection<C, T>(
615    values: &C,
616    kind: FieldKind,
617    field_name: &'static str,
618) -> Result<Vec<u8>, InternalError>
619where
620    C: Collection<Item = T>,
621    T: PersistedByKindCodec,
622{
623    let (FieldKind::List(inner) | FieldKind::Set(inner)) = kind else {
624        return Err(InternalError::persisted_row_field_encode_failed(
625            field_name,
626            format!("field kind {kind:?} does not accept collection payloads"),
627        ));
628    };
629
630    let item_bytes = values
631        .iter()
632        .map(|item| item.encode_persisted_slot_payload_by_kind(*inner, field_name))
633        .collect::<Result<Vec<_>, _>>()?;
634    let item_slices = item_bytes.iter().map(Vec::as_slice).collect::<Vec<_>>();
635
636    encode_list_field_items(item_slices.as_slice(), kind, field_name)
637}
638
639// Decode one collection wrapper through recursive by-kind item ownership
640// instead of re-entering the generic runtime `Value` bridge.
641fn decode_direct_by_kind_collection<T>(
642    bytes: &[u8],
643    kind: FieldKind,
644    field_name: &'static str,
645) -> Result<Vec<T>, InternalError>
646where
647    T: PersistedByKindCodec,
648{
649    let (FieldKind::List(inner) | FieldKind::Set(inner)) = kind else {
650        return Err(InternalError::persisted_row_field_decode_failed(
651            field_name,
652            format!("field kind {kind:?} does not accept collection payloads"),
653        ));
654    };
655
656    let item_bytes = decode_list_field_items(bytes, kind)
657        .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))?;
658
659    item_bytes
660        .iter()
661        .map(|item| decode_required_nested_by_kind(item.as_slice(), *inner, field_name, "item"))
662        .collect()
663}
664
665// Encode one map wrapper through recursive by-kind key/value ownership instead
666// of re-entering the generic runtime `Value` bridge.
667fn encode_direct_by_kind_map<K, V>(
668    entries: &BTreeMap<K, V>,
669    kind: FieldKind,
670    field_name: &'static str,
671) -> Result<Vec<u8>, InternalError>
672where
673    K: Ord + PersistedByKindCodec,
674    V: PersistedByKindCodec,
675{
676    let FieldKind::Map {
677        key,
678        value: value_kind,
679    } = kind
680    else {
681        return Err(InternalError::persisted_row_field_encode_failed(
682            field_name,
683            format!("field kind {kind:?} does not accept map payloads"),
684        ));
685    };
686
687    let entry_bytes = entries
688        .iter()
689        .map(|(entry_key, entry_value)| {
690            let key_bytes = entry_key.encode_persisted_slot_payload_by_kind(*key, field_name)?;
691            let value_bytes =
692                entry_value.encode_persisted_slot_payload_by_kind(*value_kind, field_name)?;
693
694            Ok((key_bytes, value_bytes))
695        })
696        .collect::<Result<Vec<_>, InternalError>>()?;
697    let entry_slices = entry_bytes
698        .iter()
699        .map(|(key_bytes, value_bytes)| (key_bytes.as_slice(), value_bytes.as_slice()))
700        .collect::<Vec<_>>();
701
702    encode_map_field_entries(entry_slices.as_slice(), kind, field_name)
703}
704
705// Decode one map wrapper through recursive by-kind key/value ownership instead
706// of re-entering the generic runtime `Value` bridge.
707fn decode_direct_by_kind_map<K, V>(
708    bytes: &[u8],
709    kind: FieldKind,
710    field_name: &'static str,
711) -> Result<BTreeMap<K, V>, InternalError>
712where
713    K: Ord + PersistedByKindCodec,
714    V: PersistedByKindCodec,
715{
716    let FieldKind::Map {
717        key,
718        value: value_kind,
719    } = kind
720    else {
721        return Err(InternalError::persisted_row_field_decode_failed(
722            field_name,
723            format!("field kind {kind:?} does not accept map payloads"),
724        ));
725    };
726
727    let entry_bytes = decode_map_field_entries(bytes, kind)
728        .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))?;
729    let mut decoded = BTreeMap::new();
730    for (key_bytes, value_bytes) in entry_bytes {
731        let decoded_key =
732            decode_required_nested_by_kind(key_bytes.as_slice(), *key, field_name, "map key")?;
733        let decoded_value = decode_required_nested_by_kind(
734            value_bytes.as_slice(),
735            *value_kind,
736            field_name,
737            "map value",
738        )?;
739        decoded.insert(decoded_key, decoded_value);
740    }
741
742    Ok(decoded)
743}
744
745impl<T> PersistedByKindCodec for Vec<T>
746where
747    T: PersistedByKindCodec,
748{
749    fn encode_persisted_slot_payload_by_kind(
750        &self,
751        kind: FieldKind,
752        field_name: &'static str,
753    ) -> Result<Vec<u8>, InternalError> {
754        encode_direct_by_kind_collection(self, kind, field_name)
755    }
756
757    fn decode_persisted_option_slot_payload_by_kind(
758        bytes: &[u8],
759        kind: FieldKind,
760        field_name: &'static str,
761    ) -> Result<Option<Self>, InternalError> {
762        decode_direct_by_kind_collection(bytes, kind, field_name).map(Some)
763    }
764}
765
766impl<T> PersistedByKindCodec for BTreeSet<T>
767where
768    T: Ord + PersistedByKindCodec,
769{
770    fn encode_persisted_slot_payload_by_kind(
771        &self,
772        kind: FieldKind,
773        field_name: &'static str,
774    ) -> Result<Vec<u8>, InternalError> {
775        encode_direct_by_kind_collection(self, kind, field_name)
776    }
777
778    fn decode_persisted_option_slot_payload_by_kind(
779        bytes: &[u8],
780        kind: FieldKind,
781        field_name: &'static str,
782    ) -> Result<Option<Self>, InternalError> {
783        decode_direct_by_kind_collection::<T>(bytes, kind, field_name)
784            .map(|values| Some(values.into_iter().collect()))
785    }
786}
787
788impl<K, V> PersistedByKindCodec for BTreeMap<K, V>
789where
790    K: Ord + PersistedByKindCodec,
791    V: PersistedByKindCodec,
792{
793    fn encode_persisted_slot_payload_by_kind(
794        &self,
795        kind: FieldKind,
796        field_name: &'static str,
797    ) -> Result<Vec<u8>, InternalError> {
798        encode_direct_by_kind_map(self, kind, field_name)
799    }
800
801    fn decode_persisted_option_slot_payload_by_kind(
802        bytes: &[u8],
803        kind: FieldKind,
804        field_name: &'static str,
805    ) -> Result<Option<Self>, InternalError> {
806        decode_direct_by_kind_map(bytes, kind, field_name).map(Some)
807    }
808}
809
810/// Decode one persisted slot payload using the field type's own runtime field
811/// metadata.
812pub fn decode_persisted_slot_payload_by_meta<T>(
813    bytes: &[u8],
814    field_name: &'static str,
815) -> Result<T, InternalError>
816where
817    T: PersistedFieldMetaCodec,
818{
819    T::decode_persisted_slot_payload_by_meta(bytes, field_name)
820}
821
822/// Decode one optional persisted slot payload using the inner field type's own
823/// runtime field metadata.
824pub fn decode_persisted_option_slot_payload_by_meta<T>(
825    bytes: &[u8],
826    field_name: &'static str,
827) -> Result<Option<T>, InternalError>
828where
829    T: PersistedFieldMetaCodec,
830{
831    T::decode_persisted_option_slot_payload_by_meta(bytes, field_name)
832}
833
834macro_rules! impl_persisted_structured_signed_scalar_codec {
835    ($($ty:ty),* $(,)?) => {
836        $(
837            impl PersistedStructuredFieldCodec for $ty {
838                fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
839                    Ok(encode_structural_value_storage_i64_bytes(i64::from(*self)))
840                }
841
842                fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
843                    let value = decode_structural_value_storage_i64_bytes(bytes)
844                        .map_err(InternalError::persisted_row_decode_failed)?;
845
846                    <$ty>::try_from(value).map_err(|_| {
847                        InternalError::persisted_row_decode_failed(format!(
848                            "value payload does not match {}",
849                            std::any::type_name::<$ty>()
850                        ))
851                    })
852                }
853            }
854        )*
855    };
856}
857
858macro_rules! impl_persisted_structured_unsigned_scalar_codec {
859    ($($ty:ty),* $(,)?) => {
860        $(
861            impl PersistedStructuredFieldCodec for $ty {
862                fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
863                    Ok(encode_structural_value_storage_u64_bytes(u64::from(*self)))
864                }
865
866                fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
867                    let value = decode_structural_value_storage_u64_bytes(bytes)
868                        .map_err(InternalError::persisted_row_decode_failed)?;
869
870                    <$ty>::try_from(value).map_err(|_| {
871                        InternalError::persisted_row_decode_failed(format!(
872                            "value payload does not match {}",
873                            std::any::type_name::<$ty>()
874                        ))
875                    })
876                }
877            }
878        )*
879    };
880}
881
882impl PersistedStructuredFieldCodec for bool {
883    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
884        Ok(encode_structural_value_storage_bool_bytes(*self))
885    }
886
887    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
888        decode_structural_value_storage_bool_bytes(bytes)
889            .map_err(InternalError::persisted_row_decode_failed)
890    }
891}
892
893impl PersistedStructuredFieldCodec for String {
894    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
895        Ok(encode_text(self))
896    }
897
898    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
899        decode_text(bytes).map_err(InternalError::persisted_row_decode_failed)
900    }
901}
902
903impl PersistedStructuredFieldCodec for Blob {
904    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
905        Ok(encode_structural_value_storage_blob_bytes(self.as_slice()))
906    }
907
908    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
909        decode_structural_value_storage_blob_bytes(bytes)
910            .map(Self::from)
911            .map_err(InternalError::persisted_row_decode_failed)
912    }
913}
914
915impl PersistedStructuredFieldCodec for Account {
916    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
917        encode_account(*self)
918    }
919
920    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
921        decode_account(bytes).map_err(InternalError::persisted_row_decode_failed)
922    }
923}
924
925impl PersistedStructuredFieldCodec for Decimal {
926    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
927        Ok(encode_decimal(*self))
928    }
929
930    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
931        decode_decimal(bytes).map_err(InternalError::persisted_row_decode_failed)
932    }
933}
934
935impl PersistedStructuredFieldCodec for Float32 {
936    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
937        Ok(encode_structural_value_storage_float32_bytes(*self))
938    }
939
940    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
941        decode_structural_value_storage_float32_bytes(bytes)
942            .map_err(InternalError::persisted_row_decode_failed)
943    }
944}
945
946impl PersistedStructuredFieldCodec for Float64 {
947    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
948        Ok(encode_structural_value_storage_float64_bytes(*self))
949    }
950
951    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
952        decode_structural_value_storage_float64_bytes(bytes)
953            .map_err(InternalError::persisted_row_decode_failed)
954    }
955}
956
957impl PersistedStructuredFieldCodec for Principal {
958    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
959        encode_structural_value_storage_principal_bytes(*self)
960    }
961
962    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
963        decode_structural_value_storage_principal_bytes(bytes)
964            .map_err(InternalError::persisted_row_decode_failed)
965    }
966}
967
968impl PersistedStructuredFieldCodec for Subaccount {
969    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
970        Ok(encode_structural_value_storage_subaccount_bytes(*self))
971    }
972
973    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
974        decode_structural_value_storage_subaccount_bytes(bytes)
975            .map_err(InternalError::persisted_row_decode_failed)
976    }
977}
978
979impl PersistedStructuredFieldCodec for Timestamp {
980    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
981        Ok(encode_structural_value_storage_timestamp_bytes(*self))
982    }
983
984    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
985        decode_structural_value_storage_timestamp_bytes(bytes)
986            .map_err(InternalError::persisted_row_decode_failed)
987    }
988}
989
990impl PersistedStructuredFieldCodec for Date {
991    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
992        Ok(encode_structural_value_storage_date_bytes(*self))
993    }
994
995    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
996        decode_structural_value_storage_date_bytes(bytes)
997            .map_err(InternalError::persisted_row_decode_failed)
998    }
999}
1000
1001impl PersistedStructuredFieldCodec for Duration {
1002    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1003        Ok(encode_structural_value_storage_duration_bytes(*self))
1004    }
1005
1006    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1007        decode_structural_value_storage_duration_bytes(bytes)
1008            .map_err(InternalError::persisted_row_decode_failed)
1009    }
1010}
1011
1012impl PersistedStructuredFieldCodec for Ulid {
1013    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1014        Ok(encode_structural_value_storage_ulid_bytes(*self))
1015    }
1016
1017    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1018        decode_structural_value_storage_ulid_bytes(bytes)
1019            .map_err(InternalError::persisted_row_decode_failed)
1020    }
1021}
1022
1023impl PersistedStructuredFieldCodec for Int128 {
1024    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1025        Ok(encode_int128(*self))
1026    }
1027
1028    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1029        decode_int128(bytes).map_err(InternalError::persisted_row_decode_failed)
1030    }
1031}
1032
1033impl PersistedStructuredFieldCodec for Nat128 {
1034    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1035        Ok(encode_nat128(*self))
1036    }
1037
1038    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1039        decode_nat128(bytes).map_err(InternalError::persisted_row_decode_failed)
1040    }
1041}
1042
1043impl PersistedStructuredFieldCodec for Int {
1044    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1045        Ok(encode_int(self))
1046    }
1047
1048    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1049        decode_int(bytes).map_err(InternalError::persisted_row_decode_failed)
1050    }
1051}
1052
1053impl PersistedStructuredFieldCodec for Nat {
1054    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1055        Ok(encode_nat(self))
1056    }
1057
1058    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1059        decode_nat(bytes).map_err(InternalError::persisted_row_decode_failed)
1060    }
1061}
1062
1063impl PersistedStructuredFieldCodec for Unit {
1064    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1065        Ok(encode_structural_value_storage_unit_bytes())
1066    }
1067
1068    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1069        decode_structural_value_storage_unit_bytes(bytes)
1070            .map(|()| Self)
1071            .map_err(InternalError::persisted_row_decode_failed)
1072    }
1073}
1074
1075// `Value` remains an explicit runtime/dynamic escape hatch for callers that
1076// intentionally want to persist one already-materialized runtime union.
1077// This is not a generic fallback: normal typed persistence should use
1078// `PersistedStructuredFieldCodec` or `PersistedByKindCodec` on the concrete
1079// field type instead of routing through `Value`.
1080impl PersistedStructuredFieldCodec for Value {
1081    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1082        encode_structural_value_storage_bytes(self)
1083            .map_err(InternalError::persisted_row_encode_failed)
1084    }
1085
1086    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1087        decode_structural_value_storage_bytes(bytes)
1088            .map_err(InternalError::persisted_row_decode_failed)
1089    }
1090}
1091
1092impl PersistedFieldMetaCodec for Value {
1093    fn encode_persisted_slot_payload_by_meta(
1094        &self,
1095        field_name: &'static str,
1096    ) -> Result<Vec<u8>, InternalError> {
1097        encode_persisted_custom_slot_payload(self, field_name)
1098    }
1099
1100    fn decode_persisted_slot_payload_by_meta(
1101        bytes: &[u8],
1102        field_name: &'static str,
1103    ) -> Result<Self, InternalError> {
1104        decode_persisted_custom_slot_payload(bytes, field_name)
1105    }
1106
1107    fn encode_persisted_option_slot_payload_by_meta(
1108        value: &Option<Self>,
1109        field_name: &'static str,
1110    ) -> Result<Vec<u8>, InternalError> {
1111        encode_persisted_custom_slot_payload(value, field_name)
1112    }
1113
1114    fn decode_persisted_option_slot_payload_by_meta(
1115        bytes: &[u8],
1116        field_name: &'static str,
1117    ) -> Result<Option<Self>, InternalError> {
1118        decode_persisted_custom_slot_payload(bytes, field_name)
1119    }
1120}
1121
1122impl_persisted_structured_signed_scalar_codec!(i8, i16, i32, i64);
1123impl_persisted_structured_unsigned_scalar_codec!(u8, u16, u32, u64);
1124
1125impl<T> PersistedStructuredFieldCodec for Vec<T>
1126where
1127    T: PersistedStructuredFieldCodec,
1128{
1129    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1130        let item_payloads = self
1131            .iter()
1132            .map(PersistedStructuredFieldCodec::encode_persisted_structured_payload)
1133            .collect::<Result<Vec<_>, _>>()?;
1134        let item_slices = item_payloads.iter().map(Vec::as_slice).collect::<Vec<_>>();
1135
1136        Ok(encode_list_item(item_slices.as_slice()))
1137    }
1138
1139    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1140        let item_bytes =
1141            decode_list_item(bytes).map_err(InternalError::persisted_row_decode_failed)?;
1142
1143        item_bytes
1144            .into_iter()
1145            .map(T::decode_persisted_structured_payload)
1146            .collect()
1147    }
1148}
1149
1150impl<T> PersistedFieldMetaCodec for Vec<T>
1151where
1152    T: PersistedFieldMetaCodec + PersistedStructuredFieldCodec,
1153{
1154    fn encode_persisted_slot_payload_by_meta(
1155        &self,
1156        field_name: &'static str,
1157    ) -> Result<Vec<u8>, InternalError> {
1158        encode_persisted_custom_slot_payload(self, field_name)
1159    }
1160
1161    fn decode_persisted_slot_payload_by_meta(
1162        bytes: &[u8],
1163        field_name: &'static str,
1164    ) -> Result<Self, InternalError> {
1165        decode_persisted_custom_slot_payload(bytes, field_name)
1166    }
1167
1168    fn encode_persisted_option_slot_payload_by_meta(
1169        value: &Option<Self>,
1170        field_name: &'static str,
1171    ) -> Result<Vec<u8>, InternalError> {
1172        encode_persisted_custom_slot_payload(value, field_name)
1173    }
1174
1175    fn decode_persisted_option_slot_payload_by_meta(
1176        bytes: &[u8],
1177        field_name: &'static str,
1178    ) -> Result<Option<Self>, InternalError> {
1179        decode_persisted_custom_slot_payload(bytes, field_name)
1180    }
1181}
1182
1183impl<T> PersistedStructuredFieldCodec for Option<T>
1184where
1185    T: PersistedStructuredFieldCodec,
1186{
1187    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1188        match self {
1189            Some(value) => value.encode_persisted_structured_payload(),
1190            None => Ok(encode_structural_value_storage_null_bytes()),
1191        }
1192    }
1193
1194    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1195        if structural_value_storage_bytes_are_null(bytes)
1196            .map_err(InternalError::persisted_row_decode_failed)?
1197        {
1198            return Ok(None);
1199        }
1200
1201        T::decode_persisted_structured_payload(bytes).map(Some)
1202    }
1203}
1204
1205impl<T> PersistedStructuredFieldCodec for Box<T>
1206where
1207    T: PersistedStructuredFieldCodec,
1208{
1209    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1210        self.as_ref().encode_persisted_structured_payload()
1211    }
1212
1213    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1214        T::decode_persisted_structured_payload(bytes).map(Self::new)
1215    }
1216}
1217
1218impl<T> PersistedFieldMetaCodec for Box<T>
1219where
1220    T: PersistedFieldMetaCodec,
1221{
1222    fn encode_persisted_slot_payload_by_meta(
1223        &self,
1224        field_name: &'static str,
1225    ) -> Result<Vec<u8>, InternalError> {
1226        self.as_ref()
1227            .encode_persisted_slot_payload_by_meta(field_name)
1228    }
1229
1230    fn decode_persisted_slot_payload_by_meta(
1231        bytes: &[u8],
1232        field_name: &'static str,
1233    ) -> Result<Self, InternalError> {
1234        T::decode_persisted_slot_payload_by_meta(bytes, field_name).map(Self::new)
1235    }
1236
1237    fn encode_persisted_option_slot_payload_by_meta(
1238        value: &Option<Self>,
1239        field_name: &'static str,
1240    ) -> Result<Vec<u8>, InternalError> {
1241        match value {
1242            Some(value) => value
1243                .as_ref()
1244                .encode_persisted_slot_payload_by_meta(field_name),
1245            None => T::encode_persisted_option_slot_payload_by_meta(&None, field_name),
1246        }
1247    }
1248
1249    fn decode_persisted_option_slot_payload_by_meta(
1250        bytes: &[u8],
1251        field_name: &'static str,
1252    ) -> Result<Option<Self>, InternalError> {
1253        T::decode_persisted_option_slot_payload_by_meta(bytes, field_name)
1254            .map(|value| value.map(Self::new))
1255    }
1256}
1257
1258impl<T> PersistedStructuredFieldCodec for BTreeSet<T>
1259where
1260    T: Ord + PersistedStructuredFieldCodec,
1261{
1262    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1263        let item_payloads = self
1264            .iter()
1265            .map(PersistedStructuredFieldCodec::encode_persisted_structured_payload)
1266            .collect::<Result<Vec<_>, _>>()?;
1267        let item_slices = item_payloads.iter().map(Vec::as_slice).collect::<Vec<_>>();
1268
1269        Ok(encode_list_item(item_slices.as_slice()))
1270    }
1271
1272    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1273        let item_bytes =
1274            decode_list_item(bytes).map_err(InternalError::persisted_row_decode_failed)?;
1275        let mut out = Self::new();
1276        for item_bytes in item_bytes {
1277            let item = T::decode_persisted_structured_payload(item_bytes)?;
1278            if !out.insert(item) {
1279                return Err(InternalError::persisted_row_decode_failed(format!(
1280                    "value payload does not match BTreeSet<{}>",
1281                    std::any::type_name::<T>()
1282                )));
1283            }
1284        }
1285
1286        Ok(out)
1287    }
1288}
1289
1290impl<T> PersistedFieldMetaCodec for BTreeSet<T>
1291where
1292    T: Ord + PersistedFieldMetaCodec + PersistedStructuredFieldCodec,
1293{
1294    fn encode_persisted_slot_payload_by_meta(
1295        &self,
1296        field_name: &'static str,
1297    ) -> Result<Vec<u8>, InternalError> {
1298        encode_persisted_custom_slot_payload(self, field_name)
1299    }
1300
1301    fn decode_persisted_slot_payload_by_meta(
1302        bytes: &[u8],
1303        field_name: &'static str,
1304    ) -> Result<Self, InternalError> {
1305        decode_persisted_custom_slot_payload(bytes, field_name)
1306    }
1307
1308    fn encode_persisted_option_slot_payload_by_meta(
1309        value: &Option<Self>,
1310        field_name: &'static str,
1311    ) -> Result<Vec<u8>, InternalError> {
1312        encode_persisted_custom_slot_payload(value, field_name)
1313    }
1314
1315    fn decode_persisted_option_slot_payload_by_meta(
1316        bytes: &[u8],
1317        field_name: &'static str,
1318    ) -> Result<Option<Self>, InternalError> {
1319        decode_persisted_custom_slot_payload(bytes, field_name)
1320    }
1321}
1322
1323impl<K, V> PersistedStructuredFieldCodec for BTreeMap<K, V>
1324where
1325    K: Ord + PersistedStructuredFieldCodec,
1326    V: PersistedStructuredFieldCodec,
1327{
1328    fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError> {
1329        let entry_payloads = self
1330            .iter()
1331            .map(|(key, value)| {
1332                Ok((
1333                    key.encode_persisted_structured_payload()?,
1334                    value.encode_persisted_structured_payload()?,
1335                ))
1336            })
1337            .collect::<Result<Vec<_>, InternalError>>()?;
1338        let entry_slices = entry_payloads
1339            .iter()
1340            .map(|(key_bytes, value_bytes)| (key_bytes.as_slice(), value_bytes.as_slice()))
1341            .collect::<Vec<_>>();
1342
1343        Ok(encode_map_entry(entry_slices.as_slice()))
1344    }
1345
1346    fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError> {
1347        let entry_bytes =
1348            decode_map_entry(bytes).map_err(InternalError::persisted_row_decode_failed)?;
1349        let mut out = Self::new();
1350        for (key_bytes, value_bytes) in entry_bytes {
1351            let key = K::decode_persisted_structured_payload(key_bytes)?;
1352            let value = V::decode_persisted_structured_payload(value_bytes)?;
1353
1354            if let Some((previous_key, _)) = out.last_key_value()
1355                && key <= *previous_key
1356            {
1357                return Err(InternalError::persisted_row_decode_failed(format!(
1358                    "value payload does not match BTreeMap<{}, {}>",
1359                    std::any::type_name::<K>(),
1360                    std::any::type_name::<V>()
1361                )));
1362            }
1363            if out.insert(key, value).is_some() {
1364                return Err(InternalError::persisted_row_decode_failed(format!(
1365                    "value payload does not match BTreeMap<{}, {}>",
1366                    std::any::type_name::<K>(),
1367                    std::any::type_name::<V>()
1368                )));
1369            }
1370        }
1371
1372        Ok(out)
1373    }
1374}
1375
1376impl<K, V> PersistedFieldMetaCodec for BTreeMap<K, V>
1377where
1378    K: Ord + PersistedFieldMetaCodec + PersistedStructuredFieldCodec,
1379    V: PersistedFieldMetaCodec + PersistedStructuredFieldCodec,
1380{
1381    fn encode_persisted_slot_payload_by_meta(
1382        &self,
1383        field_name: &'static str,
1384    ) -> Result<Vec<u8>, InternalError> {
1385        encode_persisted_custom_slot_payload(self, field_name)
1386    }
1387
1388    fn decode_persisted_slot_payload_by_meta(
1389        bytes: &[u8],
1390        field_name: &'static str,
1391    ) -> Result<Self, InternalError> {
1392        decode_persisted_custom_slot_payload(bytes, field_name)
1393    }
1394
1395    fn encode_persisted_option_slot_payload_by_meta(
1396        value: &Option<Self>,
1397        field_name: &'static str,
1398    ) -> Result<Vec<u8>, InternalError> {
1399        encode_persisted_custom_slot_payload(value, field_name)
1400    }
1401
1402    fn decode_persisted_option_slot_payload_by_meta(
1403        bytes: &[u8],
1404        field_name: &'static str,
1405    ) -> Result<Option<Self>, InternalError> {
1406        decode_persisted_custom_slot_payload(bytes, field_name)
1407    }
1408}
1409
1410/// Decode one persisted custom-schema payload through the direct structured
1411/// field codec owner.
1412pub fn decode_persisted_custom_slot_payload<T>(
1413    bytes: &[u8],
1414    field_name: &'static str,
1415) -> Result<T, InternalError>
1416where
1417    T: PersistedStructuredFieldCodec,
1418{
1419    T::decode_persisted_structured_payload(bytes)
1420        .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))
1421}
1422
1423/// Decode one persisted repeated custom-schema payload through the `Vec<T>`
1424/// structured codec owner.
1425pub fn decode_persisted_custom_many_slot_payload<T>(
1426    bytes: &[u8],
1427    field_name: &'static str,
1428) -> Result<Vec<T>, InternalError>
1429where
1430    Vec<T>: PersistedStructuredFieldCodec,
1431{
1432    <Vec<T>>::decode_persisted_structured_payload(bytes)
1433        .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))
1434}
1435
1436/// Encode one custom-schema field payload through the direct structured field
1437/// codec owner.
1438pub fn encode_persisted_custom_slot_payload<T>(
1439    value: &T,
1440    field_name: &'static str,
1441) -> Result<Vec<u8>, InternalError>
1442where
1443    T: PersistedStructuredFieldCodec,
1444{
1445    value
1446        .encode_persisted_structured_payload()
1447        .map_err(|err| InternalError::persisted_row_field_encode_failed(field_name, err))
1448}
1449
1450/// Encode one repeated custom-schema payload through the `Vec<T>` structured
1451/// codec owner.
1452pub fn encode_persisted_custom_many_slot_payload<T>(
1453    values: &[T],
1454    field_name: &'static str,
1455) -> Result<Vec<u8>, InternalError>
1456where
1457    T: Clone,
1458    Vec<T>: PersistedStructuredFieldCodec,
1459{
1460    values
1461        .to_vec()
1462        .encode_persisted_structured_payload()
1463        .map_err(|err| InternalError::persisted_row_field_encode_failed(field_name, err))
1464}
1465
1466/// Encode one persisted slot payload using the field type's own runtime field
1467/// metadata.
1468pub fn encode_persisted_slot_payload_by_meta<T>(
1469    value: &T,
1470    field_name: &'static str,
1471) -> Result<Vec<u8>, InternalError>
1472where
1473    T: PersistedFieldMetaCodec,
1474{
1475    value.encode_persisted_slot_payload_by_meta(field_name)
1476}
1477
1478/// Encode one optional persisted slot payload using the inner field type's own
1479/// runtime field metadata.
1480pub fn encode_persisted_option_slot_payload_by_meta<T>(
1481    value: &Option<T>,
1482    field_name: &'static str,
1483) -> Result<Vec<u8>, InternalError>
1484where
1485    T: PersistedFieldMetaCodec,
1486{
1487    T::encode_persisted_option_slot_payload_by_meta(value, field_name)
1488}
1489
1490/// Decode one persisted scalar slot payload using the canonical scalar envelope.
1491pub fn decode_persisted_scalar_slot_payload<T>(
1492    bytes: &[u8],
1493    field_name: &'static str,
1494) -> Result<T, InternalError>
1495where
1496    T: PersistedScalar,
1497{
1498    let payload = decode_scalar_slot_payload_body(bytes, field_name)?.ok_or_else(|| {
1499        InternalError::persisted_row_field_decode_failed(
1500            field_name,
1501            "unexpected null for non-nullable scalar field",
1502        )
1503    })?;
1504
1505    T::decode_scalar_payload(payload, field_name)
1506}
1507
1508/// Decode one optional persisted scalar slot payload preserving explicit `NULL`.
1509pub fn decode_persisted_option_scalar_slot_payload<T>(
1510    bytes: &[u8],
1511    field_name: &'static str,
1512) -> Result<Option<T>, InternalError>
1513where
1514    T: PersistedScalar,
1515{
1516    let Some(payload) = decode_scalar_slot_payload_body(bytes, field_name)? else {
1517        return Ok(None);
1518    };
1519
1520    T::decode_scalar_payload(payload, field_name).map(Some)
1521}
1522
1523// Encode one scalar slot value into the canonical prefixed scalar envelope.
1524pub(super) fn encode_scalar_slot_value(value: ScalarSlotValueRef<'_>) -> Vec<u8> {
1525    match value {
1526        ScalarSlotValueRef::Null => vec![SCALAR_SLOT_PREFIX, SCALAR_SLOT_TAG_NULL],
1527        ScalarSlotValueRef::Value(value) => {
1528            let mut encoded = Vec::new();
1529            encoded.push(SCALAR_SLOT_PREFIX);
1530            encoded.push(SCALAR_SLOT_TAG_VALUE);
1531
1532            match value {
1533                ScalarValueRef::Blob(bytes) => encoded.extend_from_slice(bytes),
1534                ScalarValueRef::Bool(value) => encoded.push(u8::from(value)),
1535                ScalarValueRef::Date(value) => {
1536                    encoded.extend_from_slice(&value.as_days_since_epoch().to_le_bytes());
1537                }
1538                ScalarValueRef::Duration(value) => {
1539                    encoded.extend_from_slice(&value.as_millis().to_le_bytes());
1540                }
1541                ScalarValueRef::Float32(value) => {
1542                    encoded.extend_from_slice(&value.get().to_bits().to_le_bytes());
1543                }
1544                ScalarValueRef::Float64(value) => {
1545                    encoded.extend_from_slice(&value.get().to_bits().to_le_bytes());
1546                }
1547                ScalarValueRef::Int(value) => encoded.extend_from_slice(&value.to_le_bytes()),
1548                ScalarValueRef::Principal(value) => encoded.extend_from_slice(value.as_slice()),
1549                ScalarValueRef::Subaccount(value) => encoded.extend_from_slice(&value.to_bytes()),
1550                ScalarValueRef::Text(value) => encoded.extend_from_slice(value.as_bytes()),
1551                ScalarValueRef::Timestamp(value) => {
1552                    encoded.extend_from_slice(&value.as_millis().to_le_bytes());
1553                }
1554                ScalarValueRef::Uint(value) => encoded.extend_from_slice(&value.to_le_bytes()),
1555                ScalarValueRef::Ulid(value) => encoded.extend_from_slice(&value.to_bytes()),
1556                ScalarValueRef::Unit => {}
1557            }
1558
1559            encoded
1560        }
1561    }
1562}
1563
1564// Split one scalar slot envelope into `NULL` vs payload bytes.
1565fn decode_scalar_slot_payload_body<'a>(
1566    bytes: &'a [u8],
1567    field_name: &'static str,
1568) -> Result<Option<&'a [u8]>, InternalError> {
1569    let Some((&prefix, rest)) = bytes.split_first() else {
1570        return Err(InternalError::persisted_row_field_decode_failed(
1571            field_name,
1572            "empty scalar payload",
1573        ));
1574    };
1575    if prefix != SCALAR_SLOT_PREFIX {
1576        return Err(InternalError::persisted_row_field_decode_failed(
1577            field_name,
1578            format!(
1579                "scalar payload prefix mismatch: expected slot envelope prefix byte 0x{SCALAR_SLOT_PREFIX:02X}, found 0x{prefix:02X}",
1580            ),
1581        ));
1582    }
1583    let Some((&tag, payload)) = rest.split_first() else {
1584        return Err(InternalError::persisted_row_field_decode_failed(
1585            field_name,
1586            "truncated scalar payload tag",
1587        ));
1588    };
1589
1590    match tag {
1591        SCALAR_SLOT_TAG_NULL => {
1592            if !payload.is_empty() {
1593                return Err(InternalError::persisted_row_field_decode_failed(
1594                    field_name,
1595                    "null scalar payload has trailing bytes",
1596                ));
1597            }
1598
1599            Ok(None)
1600        }
1601        SCALAR_SLOT_TAG_VALUE => Ok(Some(payload)),
1602        _ => Err(InternalError::persisted_row_field_decode_failed(
1603            field_name,
1604            format!("invalid scalar payload tag {tag}"),
1605        )),
1606    }
1607}
1608
1609// Decode one scalar slot view using the field-declared scalar codec.
1610#[expect(clippy::too_many_lines)]
1611pub(super) fn decode_scalar_slot_value<'a>(
1612    bytes: &'a [u8],
1613    codec: ScalarCodec,
1614    field_name: &'static str,
1615) -> Result<ScalarSlotValueRef<'a>, InternalError> {
1616    let Some(payload) = decode_scalar_slot_payload_body(bytes, field_name)? else {
1617        return Ok(ScalarSlotValueRef::Null);
1618    };
1619
1620    let value = match codec {
1621        ScalarCodec::Blob => ScalarValueRef::Blob(payload),
1622        ScalarCodec::Bool => {
1623            let [value] = payload else {
1624                return Err(
1625                    InternalError::persisted_row_field_payload_exact_len_required(
1626                        field_name,
1627                        "bool",
1628                        SCALAR_BOOL_PAYLOAD_LEN,
1629                    ),
1630                );
1631            };
1632            match *value {
1633                SCALAR_BOOL_FALSE_TAG => ScalarValueRef::Bool(false),
1634                SCALAR_BOOL_TRUE_TAG => ScalarValueRef::Bool(true),
1635                _ => {
1636                    return Err(InternalError::persisted_row_field_payload_invalid_byte(
1637                        field_name, "bool", *value,
1638                    ));
1639                }
1640            }
1641        }
1642        ScalarCodec::Date => {
1643            let bytes: [u8; SCALAR_WORD32_PAYLOAD_LEN] = payload.try_into().map_err(|_| {
1644                InternalError::persisted_row_field_payload_exact_len_required(
1645                    field_name,
1646                    "date",
1647                    SCALAR_WORD32_PAYLOAD_LEN,
1648                )
1649            })?;
1650            ScalarValueRef::Date(Date::from_days_since_epoch(i32::from_le_bytes(bytes)))
1651        }
1652        ScalarCodec::Duration => {
1653            let bytes: [u8; SCALAR_WORD64_PAYLOAD_LEN] = payload.try_into().map_err(|_| {
1654                InternalError::persisted_row_field_payload_exact_len_required(
1655                    field_name,
1656                    "duration",
1657                    SCALAR_WORD64_PAYLOAD_LEN,
1658                )
1659            })?;
1660            ScalarValueRef::Duration(Duration::from_millis(u64::from_le_bytes(bytes)))
1661        }
1662        ScalarCodec::Float32 => {
1663            let bytes: [u8; SCALAR_WORD32_PAYLOAD_LEN] = payload.try_into().map_err(|_| {
1664                InternalError::persisted_row_field_payload_exact_len_required(
1665                    field_name,
1666                    "float32",
1667                    SCALAR_WORD32_PAYLOAD_LEN,
1668                )
1669            })?;
1670            let value = f32::from_bits(u32::from_le_bytes(bytes));
1671            let value = Float32::try_new(value).ok_or_else(|| {
1672                InternalError::persisted_row_field_payload_non_finite(field_name, "float32")
1673            })?;
1674            ScalarValueRef::Float32(value)
1675        }
1676        ScalarCodec::Float64 => {
1677            let bytes: [u8; SCALAR_WORD64_PAYLOAD_LEN] = payload.try_into().map_err(|_| {
1678                InternalError::persisted_row_field_payload_exact_len_required(
1679                    field_name,
1680                    "float64",
1681                    SCALAR_WORD64_PAYLOAD_LEN,
1682                )
1683            })?;
1684            let value = f64::from_bits(u64::from_le_bytes(bytes));
1685            let value = Float64::try_new(value).ok_or_else(|| {
1686                InternalError::persisted_row_field_payload_non_finite(field_name, "float64")
1687            })?;
1688            ScalarValueRef::Float64(value)
1689        }
1690        ScalarCodec::Int64 => {
1691            let bytes: [u8; SCALAR_WORD64_PAYLOAD_LEN] = payload.try_into().map_err(|_| {
1692                InternalError::persisted_row_field_payload_exact_len_required(
1693                    field_name,
1694                    "int",
1695                    SCALAR_WORD64_PAYLOAD_LEN,
1696                )
1697            })?;
1698            ScalarValueRef::Int(i64::from_le_bytes(bytes))
1699        }
1700        ScalarCodec::Principal => ScalarValueRef::Principal(
1701            Principal::try_from_bytes(payload)
1702                .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))?,
1703        ),
1704        ScalarCodec::Subaccount => {
1705            let bytes: [u8; SCALAR_SUBACCOUNT_PAYLOAD_LEN] = payload.try_into().map_err(|_| {
1706                InternalError::persisted_row_field_payload_exact_len_required(
1707                    field_name,
1708                    "subaccount",
1709                    SCALAR_SUBACCOUNT_PAYLOAD_LEN,
1710                )
1711            })?;
1712            ScalarValueRef::Subaccount(Subaccount::from_array(bytes))
1713        }
1714        ScalarCodec::Text => {
1715            let value = str::from_utf8(payload).map_err(|err| {
1716                InternalError::persisted_row_field_text_payload_invalid_utf8(field_name, err)
1717            })?;
1718            ScalarValueRef::Text(value)
1719        }
1720        ScalarCodec::Timestamp => {
1721            let bytes: [u8; SCALAR_WORD64_PAYLOAD_LEN] = payload.try_into().map_err(|_| {
1722                InternalError::persisted_row_field_payload_exact_len_required(
1723                    field_name,
1724                    "timestamp",
1725                    SCALAR_WORD64_PAYLOAD_LEN,
1726                )
1727            })?;
1728            ScalarValueRef::Timestamp(Timestamp::from_millis(i64::from_le_bytes(bytes)))
1729        }
1730        ScalarCodec::Uint64 => {
1731            let bytes: [u8; SCALAR_WORD64_PAYLOAD_LEN] = payload.try_into().map_err(|_| {
1732                InternalError::persisted_row_field_payload_exact_len_required(
1733                    field_name,
1734                    "uint",
1735                    SCALAR_WORD64_PAYLOAD_LEN,
1736                )
1737            })?;
1738            ScalarValueRef::Uint(u64::from_le_bytes(bytes))
1739        }
1740        ScalarCodec::Ulid => {
1741            let bytes: [u8; SCALAR_ULID_PAYLOAD_LEN] = payload.try_into().map_err(|_| {
1742                InternalError::persisted_row_field_payload_exact_len_required(
1743                    field_name,
1744                    "ulid",
1745                    SCALAR_ULID_PAYLOAD_LEN,
1746                )
1747            })?;
1748            ScalarValueRef::Ulid(Ulid::from_bytes(bytes))
1749        }
1750        ScalarCodec::Unit => {
1751            if !payload.is_empty() {
1752                return Err(InternalError::persisted_row_field_payload_must_be_empty(
1753                    field_name, "unit",
1754                ));
1755            }
1756            ScalarValueRef::Unit
1757        }
1758    };
1759
1760    Ok(ScalarSlotValueRef::Value(value))
1761}
1762
1763macro_rules! impl_persisted_scalar_signed {
1764    ($($ty:ty),* $(,)?) => {
1765        $(
1766            impl PersistedScalar for $ty {
1767                const CODEC: ScalarCodec = ScalarCodec::Int64;
1768
1769                fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
1770                    Ok(i64::from(*self).to_le_bytes().to_vec())
1771                }
1772
1773                fn decode_scalar_payload(
1774                    bytes: &[u8],
1775                    field_name: &'static str,
1776                ) -> Result<Self, InternalError> {
1777                    let raw: [u8; SCALAR_WORD64_PAYLOAD_LEN] = bytes.try_into().map_err(|_| {
1778                        InternalError::persisted_row_field_payload_exact_len_required(
1779                            field_name,
1780                            "int",
1781                            SCALAR_WORD64_PAYLOAD_LEN,
1782                        )
1783                    })?;
1784                    <$ty>::try_from(i64::from_le_bytes(raw)).map_err(|_| {
1785                        InternalError::persisted_row_field_payload_out_of_range(
1786                            field_name,
1787                            "integer",
1788                        )
1789                    })
1790                }
1791            }
1792        )*
1793    };
1794}
1795
1796macro_rules! impl_persisted_scalar_unsigned {
1797    ($($ty:ty),* $(,)?) => {
1798        $(
1799            impl PersistedScalar for $ty {
1800                const CODEC: ScalarCodec = ScalarCodec::Uint64;
1801
1802                fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
1803                    Ok(u64::from(*self).to_le_bytes().to_vec())
1804                }
1805
1806                fn decode_scalar_payload(
1807                    bytes: &[u8],
1808                    field_name: &'static str,
1809                ) -> Result<Self, InternalError> {
1810                    let raw: [u8; SCALAR_WORD64_PAYLOAD_LEN] = bytes.try_into().map_err(|_| {
1811                        InternalError::persisted_row_field_payload_exact_len_required(
1812                            field_name,
1813                            "uint",
1814                            SCALAR_WORD64_PAYLOAD_LEN,
1815                        )
1816                    })?;
1817                    <$ty>::try_from(u64::from_le_bytes(raw)).map_err(|_| {
1818                        InternalError::persisted_row_field_payload_out_of_range(
1819                            field_name,
1820                            "unsigned",
1821                        )
1822                    })
1823                }
1824            }
1825        )*
1826    };
1827}
1828
1829impl_persisted_scalar_signed!(i8, i16, i32, i64);
1830impl_persisted_scalar_unsigned!(u8, u16, u32, u64);
1831
1832impl PersistedScalar for bool {
1833    const CODEC: ScalarCodec = ScalarCodec::Bool;
1834
1835    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
1836        Ok(vec![u8::from(*self)])
1837    }
1838
1839    fn decode_scalar_payload(
1840        bytes: &[u8],
1841        field_name: &'static str,
1842    ) -> Result<Self, InternalError> {
1843        let [value] = bytes else {
1844            return Err(
1845                InternalError::persisted_row_field_payload_exact_len_required(
1846                    field_name,
1847                    "bool",
1848                    SCALAR_BOOL_PAYLOAD_LEN,
1849                ),
1850            );
1851        };
1852
1853        match *value {
1854            SCALAR_BOOL_FALSE_TAG => Ok(false),
1855            SCALAR_BOOL_TRUE_TAG => Ok(true),
1856            _ => Err(InternalError::persisted_row_field_payload_invalid_byte(
1857                field_name, "bool", *value,
1858            )),
1859        }
1860    }
1861}
1862
1863impl PersistedScalar for String {
1864    const CODEC: ScalarCodec = ScalarCodec::Text;
1865
1866    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
1867        Ok(self.as_bytes().to_vec())
1868    }
1869
1870    fn decode_scalar_payload(
1871        bytes: &[u8],
1872        field_name: &'static str,
1873    ) -> Result<Self, InternalError> {
1874        str::from_utf8(bytes).map(str::to_owned).map_err(|err| {
1875            InternalError::persisted_row_field_text_payload_invalid_utf8(field_name, err)
1876        })
1877    }
1878}
1879
1880impl PersistedScalar for Vec<u8> {
1881    const CODEC: ScalarCodec = ScalarCodec::Blob;
1882
1883    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
1884        Ok(self.clone())
1885    }
1886
1887    fn decode_scalar_payload(
1888        bytes: &[u8],
1889        _field_name: &'static str,
1890    ) -> Result<Self, InternalError> {
1891        Ok(bytes.to_vec())
1892    }
1893}
1894
1895impl PersistedScalar for Blob {
1896    const CODEC: ScalarCodec = ScalarCodec::Blob;
1897
1898    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
1899        Ok(self.to_vec())
1900    }
1901
1902    fn decode_scalar_payload(
1903        bytes: &[u8],
1904        _field_name: &'static str,
1905    ) -> Result<Self, InternalError> {
1906        Ok(Self::from(bytes))
1907    }
1908}
1909
1910impl PersistedScalar for Ulid {
1911    const CODEC: ScalarCodec = ScalarCodec::Ulid;
1912
1913    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
1914        Ok(self.to_bytes().to_vec())
1915    }
1916
1917    fn decode_scalar_payload(
1918        bytes: &[u8],
1919        field_name: &'static str,
1920    ) -> Result<Self, InternalError> {
1921        Self::try_from_bytes(bytes)
1922            .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))
1923    }
1924}
1925
1926impl PersistedScalar for Timestamp {
1927    const CODEC: ScalarCodec = ScalarCodec::Timestamp;
1928
1929    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
1930        Ok(self.as_millis().to_le_bytes().to_vec())
1931    }
1932
1933    fn decode_scalar_payload(
1934        bytes: &[u8],
1935        field_name: &'static str,
1936    ) -> Result<Self, InternalError> {
1937        let raw: [u8; SCALAR_WORD64_PAYLOAD_LEN] = bytes.try_into().map_err(|_| {
1938            InternalError::persisted_row_field_payload_exact_len_required(
1939                field_name,
1940                "timestamp",
1941                SCALAR_WORD64_PAYLOAD_LEN,
1942            )
1943        })?;
1944
1945        Ok(Self::from_millis(i64::from_le_bytes(raw)))
1946    }
1947}
1948
1949impl PersistedScalar for Date {
1950    const CODEC: ScalarCodec = ScalarCodec::Date;
1951
1952    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
1953        Ok(self.as_days_since_epoch().to_le_bytes().to_vec())
1954    }
1955
1956    fn decode_scalar_payload(
1957        bytes: &[u8],
1958        field_name: &'static str,
1959    ) -> Result<Self, InternalError> {
1960        let raw: [u8; SCALAR_WORD32_PAYLOAD_LEN] = bytes.try_into().map_err(|_| {
1961            InternalError::persisted_row_field_payload_exact_len_required(
1962                field_name,
1963                "date",
1964                SCALAR_WORD32_PAYLOAD_LEN,
1965            )
1966        })?;
1967
1968        Ok(Self::from_days_since_epoch(i32::from_le_bytes(raw)))
1969    }
1970}
1971
1972impl PersistedScalar for Duration {
1973    const CODEC: ScalarCodec = ScalarCodec::Duration;
1974
1975    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
1976        Ok(self.as_millis().to_le_bytes().to_vec())
1977    }
1978
1979    fn decode_scalar_payload(
1980        bytes: &[u8],
1981        field_name: &'static str,
1982    ) -> Result<Self, InternalError> {
1983        let raw: [u8; SCALAR_WORD64_PAYLOAD_LEN] = bytes.try_into().map_err(|_| {
1984            InternalError::persisted_row_field_payload_exact_len_required(
1985                field_name,
1986                "duration",
1987                SCALAR_WORD64_PAYLOAD_LEN,
1988            )
1989        })?;
1990
1991        Ok(Self::from_millis(u64::from_le_bytes(raw)))
1992    }
1993}
1994
1995impl PersistedScalar for Float32 {
1996    const CODEC: ScalarCodec = ScalarCodec::Float32;
1997
1998    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
1999        Ok(self.get().to_bits().to_le_bytes().to_vec())
2000    }
2001
2002    fn decode_scalar_payload(
2003        bytes: &[u8],
2004        field_name: &'static str,
2005    ) -> Result<Self, InternalError> {
2006        let raw: [u8; SCALAR_WORD32_PAYLOAD_LEN] = bytes.try_into().map_err(|_| {
2007            InternalError::persisted_row_field_payload_exact_len_required(
2008                field_name,
2009                "float32",
2010                SCALAR_WORD32_PAYLOAD_LEN,
2011            )
2012        })?;
2013        let value = f32::from_bits(u32::from_le_bytes(raw));
2014
2015        Self::try_new(value).ok_or_else(|| {
2016            InternalError::persisted_row_field_payload_non_finite(field_name, "float32")
2017        })
2018    }
2019}
2020
2021impl PersistedScalar for Float64 {
2022    const CODEC: ScalarCodec = ScalarCodec::Float64;
2023
2024    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
2025        Ok(self.get().to_bits().to_le_bytes().to_vec())
2026    }
2027
2028    fn decode_scalar_payload(
2029        bytes: &[u8],
2030        field_name: &'static str,
2031    ) -> Result<Self, InternalError> {
2032        let raw: [u8; SCALAR_WORD64_PAYLOAD_LEN] = bytes.try_into().map_err(|_| {
2033            InternalError::persisted_row_field_payload_exact_len_required(
2034                field_name,
2035                "float64",
2036                SCALAR_WORD64_PAYLOAD_LEN,
2037            )
2038        })?;
2039        let value = f64::from_bits(u64::from_le_bytes(raw));
2040
2041        Self::try_new(value).ok_or_else(|| {
2042            InternalError::persisted_row_field_payload_non_finite(field_name, "float64")
2043        })
2044    }
2045}
2046
2047impl PersistedScalar for Principal {
2048    const CODEC: ScalarCodec = ScalarCodec::Principal;
2049
2050    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
2051        self.to_bytes()
2052            .map_err(|err| InternalError::persisted_row_field_encode_failed("principal", err))
2053    }
2054
2055    fn decode_scalar_payload(
2056        bytes: &[u8],
2057        field_name: &'static str,
2058    ) -> Result<Self, InternalError> {
2059        Self::try_from_bytes(bytes)
2060            .map_err(|err| InternalError::persisted_row_field_decode_failed(field_name, err))
2061    }
2062}
2063
2064impl PersistedScalar for Subaccount {
2065    const CODEC: ScalarCodec = ScalarCodec::Subaccount;
2066
2067    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
2068        Ok(self.to_bytes().to_vec())
2069    }
2070
2071    fn decode_scalar_payload(
2072        bytes: &[u8],
2073        field_name: &'static str,
2074    ) -> Result<Self, InternalError> {
2075        let raw: [u8; SCALAR_SUBACCOUNT_PAYLOAD_LEN] = bytes.try_into().map_err(|_| {
2076            InternalError::persisted_row_field_payload_exact_len_required(
2077                field_name,
2078                "subaccount",
2079                SCALAR_SUBACCOUNT_PAYLOAD_LEN,
2080            )
2081        })?;
2082
2083        Ok(Self::from_array(raw))
2084    }
2085}
2086
2087impl PersistedScalar for () {
2088    const CODEC: ScalarCodec = ScalarCodec::Unit;
2089
2090    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
2091        Ok(Vec::new())
2092    }
2093
2094    fn decode_scalar_payload(
2095        bytes: &[u8],
2096        field_name: &'static str,
2097    ) -> Result<Self, InternalError> {
2098        if !bytes.is_empty() {
2099            return Err(InternalError::persisted_row_field_payload_must_be_empty(
2100                field_name, "unit",
2101            ));
2102        }
2103
2104        Ok(())
2105    }
2106}
2107
2108impl PersistedScalar for Unit {
2109    const CODEC: ScalarCodec = ScalarCodec::Unit;
2110
2111    fn encode_scalar_payload(&self) -> Result<Vec<u8>, InternalError> {
2112        Ok(Vec::new())
2113    }
2114
2115    fn decode_scalar_payload(
2116        bytes: &[u8],
2117        field_name: &'static str,
2118    ) -> Result<Self, InternalError> {
2119        if !bytes.is_empty() {
2120            return Err(InternalError::persisted_row_field_payload_must_be_empty(
2121                field_name, "unit",
2122            ));
2123        }
2124
2125        Ok(Self)
2126    }
2127}