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