Skip to main content

icydb_core/db/data/persisted_row/
codec.rs

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