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