1#[macro_use]
8mod macros;
9mod numeric_value;
10mod visitor;
11
12use crate::{
13 db::{CompositePrimaryKeyValueError, PrimaryKeyComponent, PrimaryKeyValue},
14 error::InternalError,
15 model::field::{FieldKind, FieldModel, FieldStorageDecode},
16 prelude::*,
17 types::{EntityTag, Id},
18 value::{InputValue, Value, ValueEnum},
19 visitor::VisitorContext,
20};
21use std::collections::{BTreeMap, BTreeSet};
22
23pub use numeric_value::*;
24pub use visitor::*;
25
26pub use ic_memory::stable_structures::storable::Storable;
31pub use serde::{Deserialize, Serialize, de::DeserializeOwned};
32pub use std::{
33 cmp::{Eq, Ordering, PartialEq},
34 convert::From,
35 default::Default,
36 fmt::Debug,
37 hash::Hash,
38 ops::{Add, AddAssign, Deref, DerefMut, Div, DivAssign, Mul, MulAssign, Rem, Sub, SubAssign},
39};
40
41pub trait Path {
55 const PATH: &'static str;
56}
57
58pub trait Kind: Path + 'static {}
64impl<T> Kind for T where T: Path + 'static {}
65
66pub trait CanisterKind: Kind {
72 const COMMIT_MEMORY_ID: u8;
74
75 const COMMIT_STABLE_KEY: &'static str;
77}
78
79pub trait StoreKind: Kind {
85 type Canister: CanisterKind;
86}
87
88pub trait EntityKey {
110 type Key: Copy
111 + Debug
112 + Eq
113 + Ord
114 + KeyValueCodec
115 + PrimaryKeyCodec
116 + PrimaryKeyDecode
117 + EntityKeyBytes
118 + 'static;
119}
120
121pub trait EntityKeyBytes {
126 const BYTE_LEN: usize;
128
129 fn write_bytes(&self, out: &mut [u8]);
131}
132
133macro_rules! impl_entity_key_bytes_numeric {
134 ($($ty:ty),* $(,)?) => {
135 $(
136 impl EntityKeyBytes for $ty {
137 const BYTE_LEN: usize = ::core::mem::size_of::<Self>();
138
139 fn write_bytes(&self, out: &mut [u8]) {
140 assert_eq!(out.len(), Self::BYTE_LEN);
141 out.copy_from_slice(&self.to_be_bytes());
142 }
143 }
144 )*
145 };
146}
147
148impl_entity_key_bytes_numeric!(i8, i16, i32, i64, i128, u8, u16, u32, u64, u128);
149
150impl EntityKeyBytes for () {
151 const BYTE_LEN: usize = 0;
152
153 fn write_bytes(&self, out: &mut [u8]) {
154 assert_eq!(out.len(), Self::BYTE_LEN);
155 }
156}
157
158pub trait ScalarRelationTargetKey {}
166
167macro_rules! impl_scalar_relation_target_key {
168 ($($ty:ty),* $(,)?) => {
169 $(
170 impl ScalarRelationTargetKey for $ty {}
171 )*
172 };
173}
174
175impl_scalar_relation_target_key!(
176 i8,
177 i16,
178 i32,
179 i64,
180 i128,
181 u8,
182 u16,
183 u32,
184 u64,
185 u128,
186 crate::types::Account,
187 crate::types::Principal,
188 crate::types::Subaccount,
189 crate::types::Timestamp,
190 crate::types::Ulid,
191 crate::types::Unit,
192 (),
193);
194
195pub trait ScalarRelationTargetKeyMatchesDeclaredPrimitive<Declared> {}
204
205impl<T> ScalarRelationTargetKeyMatchesDeclaredPrimitive<T> for T where T: ScalarRelationTargetKey {}
206
207pub trait KeyValueCodec {
217 fn to_key_value(&self) -> Value;
218
219 #[must_use]
220 fn from_key_value(value: &Value) -> Option<Self>
221 where
222 Self: Sized;
223}
224
225#[derive(Debug)]
234pub enum PrimaryKeyEncodeError {
235 UnsupportedComponentKind { kind: &'static str },
236
237 TooFewComponents { count: usize, min: usize },
238
239 TooManyComponents { count: usize, max: usize },
240
241 UnitComponent { index: usize },
242}
243
244impl From<CompositePrimaryKeyValueError> for PrimaryKeyEncodeError {
245 fn from(err: CompositePrimaryKeyValueError) -> Self {
246 match err {
247 CompositePrimaryKeyValueError::TooFewComponents { count, min } => {
248 Self::TooFewComponents { count, min }
249 }
250 CompositePrimaryKeyValueError::TooManyComponents { count, max } => {
251 Self::TooManyComponents { count, max }
252 }
253 CompositePrimaryKeyValueError::UnitComponent { index } => Self::UnitComponent { index },
254 }
255 }
256}
257
258impl From<PrimaryKeyEncodeError> for InternalError {
259 fn from(_err: PrimaryKeyEncodeError) -> Self {
260 Self::serialize_unsupported()
261 }
262}
263
264pub trait PrimaryKeyCodec {
273 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError>;
274}
275
276pub trait PrimaryKeyDecode: Sized {
286 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError>;
287}
288
289fn primary_key_variant_decode_failed(
290 _type_name: &'static str,
291 _key: &PrimaryKeyValue,
292 _expected: &'static str,
293) -> InternalError {
294 InternalError::store_corruption()
295}
296
297fn primary_key_range_decode_failed(
298 _type_name: &'static str,
299 _key: &PrimaryKeyValue,
300) -> InternalError {
301 InternalError::store_corruption()
302}
303
304macro_rules! impl_primary_key_codec_signed {
305 ($($ty:ty),* $(,)?) => {
306 $(
307 impl PrimaryKeyCodec for $ty {
308 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
309 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Int64(i64::from(*self))))
310 }
311 }
312 )*
313 };
314}
315
316macro_rules! impl_primary_key_codec_unsigned {
317 ($($ty:ty),* $(,)?) => {
318 $(
319 impl PrimaryKeyCodec for $ty {
320 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
321 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Nat64(u64::from(*self))))
322 }
323 }
324 )*
325 };
326}
327
328impl<T> KeyValueCodec for T
329where
330 T: RuntimeValueDecode + RuntimeValueEncode,
331{
332 fn to_key_value(&self) -> Value {
333 self.to_value()
334 }
335
336 fn from_key_value(value: &Value) -> Option<Self> {
337 Self::from_value(value)
338 }
339}
340
341impl_primary_key_codec_signed!(i8, i16, i32, i64);
342impl_primary_key_codec_unsigned!(u8, u16, u32, u64);
343
344impl PrimaryKeyCodec for i128 {
345 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
346 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Int128(*self)))
347 }
348}
349
350impl PrimaryKeyCodec for u128 {
351 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
352 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Nat128(*self)))
353 }
354}
355
356macro_rules! impl_primary_key_decode_signed {
357 ($($ty:ty),* $(,)?) => {
358 $(
359 impl PrimaryKeyDecode for $ty {
360 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
361 let PrimaryKeyValue::Scalar(PrimaryKeyComponent::Int64(value)) = *key else {
362 return Err(primary_key_variant_decode_failed(
363 ::std::any::type_name::<Self>(),
364 key,
365 "PrimaryKeyComponent::Int64",
366 ));
367 };
368
369 Self::try_from(value).map_err(|_| {
370 primary_key_range_decode_failed(::std::any::type_name::<Self>(), key)
371 })
372 }
373 }
374 )*
375 };
376}
377
378macro_rules! impl_primary_key_decode_unsigned {
379 ($($ty:ty),* $(,)?) => {
380 $(
381 impl PrimaryKeyDecode for $ty {
382 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
383 let PrimaryKeyValue::Scalar(PrimaryKeyComponent::Nat64(value)) = *key else {
384 return Err(primary_key_variant_decode_failed(
385 ::std::any::type_name::<Self>(),
386 key,
387 "PrimaryKeyComponent::Nat64",
388 ));
389 };
390
391 Self::try_from(value).map_err(|_| {
392 primary_key_range_decode_failed(::std::any::type_name::<Self>(), key)
393 })
394 }
395 }
396 )*
397 };
398}
399
400impl_primary_key_decode_signed!(i8, i16, i32, i64);
401impl_primary_key_decode_unsigned!(u8, u16, u32, u64);
402
403impl PrimaryKeyDecode for i128 {
404 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
405 match *key {
406 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Int128(value)) => Ok(value),
407 _ => Err(primary_key_variant_decode_failed(
408 ::std::any::type_name::<Self>(),
409 key,
410 "PrimaryKeyComponent::Int128",
411 )),
412 }
413 }
414}
415
416impl PrimaryKeyDecode for u128 {
417 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
418 match *key {
419 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Nat128(value)) => Ok(value),
420 _ => Err(primary_key_variant_decode_failed(
421 ::std::any::type_name::<Self>(),
422 key,
423 "PrimaryKeyComponent::Nat128",
424 )),
425 }
426 }
427}
428
429impl PrimaryKeyCodec for crate::types::Principal {
430 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
431 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Principal(
432 *self,
433 )))
434 }
435}
436
437impl PrimaryKeyDecode for crate::types::Principal {
438 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
439 match *key {
440 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Principal(value)) => Ok(value),
441 _ => Err(primary_key_variant_decode_failed(
442 ::std::any::type_name::<Self>(),
443 key,
444 "PrimaryKeyComponent::Principal",
445 )),
446 }
447 }
448}
449
450impl PrimaryKeyCodec for crate::types::Subaccount {
451 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
452 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Subaccount(
453 *self,
454 )))
455 }
456}
457
458impl PrimaryKeyDecode for crate::types::Subaccount {
459 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
460 match *key {
461 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Subaccount(value)) => Ok(value),
462 _ => Err(primary_key_variant_decode_failed(
463 ::std::any::type_name::<Self>(),
464 key,
465 "PrimaryKeyComponent::Subaccount",
466 )),
467 }
468 }
469}
470
471impl PrimaryKeyCodec for crate::types::Account {
472 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
473 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Account(*self)))
474 }
475}
476
477impl PrimaryKeyDecode for crate::types::Account {
478 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
479 match *key {
480 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Account(value)) => Ok(value),
481 _ => Err(primary_key_variant_decode_failed(
482 ::std::any::type_name::<Self>(),
483 key,
484 "PrimaryKeyComponent::Account",
485 )),
486 }
487 }
488}
489
490impl PrimaryKeyCodec for crate::types::Timestamp {
491 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
492 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Timestamp(
493 *self,
494 )))
495 }
496}
497
498impl PrimaryKeyDecode for crate::types::Timestamp {
499 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
500 match *key {
501 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Timestamp(value)) => Ok(value),
502 _ => Err(primary_key_variant_decode_failed(
503 ::std::any::type_name::<Self>(),
504 key,
505 "PrimaryKeyComponent::Timestamp",
506 )),
507 }
508 }
509}
510
511impl PrimaryKeyCodec for crate::types::Ulid {
512 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
513 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Ulid(*self)))
514 }
515}
516
517impl PrimaryKeyDecode for crate::types::Ulid {
518 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
519 match *key {
520 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Ulid(value)) => Ok(value),
521 _ => Err(primary_key_variant_decode_failed(
522 ::std::any::type_name::<Self>(),
523 key,
524 "PrimaryKeyComponent::Ulid",
525 )),
526 }
527 }
528}
529
530impl PrimaryKeyCodec for () {
531 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
532 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Unit))
533 }
534}
535
536impl PrimaryKeyDecode for () {
537 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
538 match *key {
539 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Unit) => Ok(()),
540 _ => Err(primary_key_variant_decode_failed(
541 ::std::any::type_name::<Self>(),
542 key,
543 "PrimaryKeyComponent::Unit",
544 )),
545 }
546 }
547}
548
549pub trait RuntimeValueEncode {
561 fn to_value(&self) -> Value;
562}
563
564pub trait RuntimeValueDecode {
575 #[must_use]
576 fn from_value(value: &Value) -> Option<Self>
577 where
578 Self: Sized;
579
580 #[doc(hidden)]
583 fn from_value_with_enum_context(
584 value: &Value,
585 _context: &dyn RuntimeEnumContext,
586 ) -> Option<Self>
587 where
588 Self: Sized,
589 {
590 Self::from_value(value)
591 }
592}
593
594#[doc(hidden)]
596pub struct RuntimeEnumSelection<'a> {
597 pub path: &'a str,
598 pub variant: &'a str,
599 pub payload: Option<&'a Value>,
600}
601
602#[doc(hidden)]
604pub trait RuntimeEnumContext {
605 fn resolve_enum<'a>(&'a self, value: &'a ValueEnum) -> Option<RuntimeEnumSelection<'a>>;
606}
607
608pub fn runtime_value_to_value<T>(value: &T) -> Value
617where
618 T: ?Sized + RuntimeValueEncode,
619{
620 value.to_value()
621}
622
623#[must_use]
632pub fn runtime_value_from_value<T>(value: &Value) -> Option<T>
633where
634 T: RuntimeValueDecode,
635{
636 T::from_value(value)
637}
638
639#[doc(hidden)]
641pub fn runtime_value_from_value_with_enum_context<T>(
642 value: &Value,
643 context: &dyn RuntimeEnumContext,
644) -> Option<T>
645where
646 T: RuntimeValueDecode,
647{
648 T::from_value_with_enum_context(value, context)
649}
650
651#[doc(hidden)]
653#[must_use]
654pub fn runtime_value_from_value_with_optional_enum_context<T>(
655 value: &Value,
656 context: Option<&dyn RuntimeEnumContext>,
657) -> Option<T>
658where
659 T: RuntimeValueDecode,
660{
661 match context {
662 Some(context) => T::from_value_with_enum_context(value, context),
663 None => T::from_value(value),
664 }
665}
666
667pub trait PersistedByKindCodec: Sized {
677 fn encode_persisted_slot_payload_by_kind(
679 &self,
680 kind: FieldKind,
681 field_name: &'static str,
682 ) -> Result<Vec<u8>, InternalError>;
683
684 fn decode_persisted_option_slot_payload_by_kind(
688 bytes: &[u8],
689 kind: FieldKind,
690 field_name: &'static str,
691 ) -> Result<Option<Self>, InternalError>;
692}
693
694pub trait PersistedStructuredFieldCodec {
706 fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError>;
708
709 fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError>
711 where
712 Self: Sized;
713}
714
715pub trait EntitySchema: EntityKey {
726 const NAME: &'static str;
727 const MODEL: &'static EntityModel;
728}
729
730pub trait EntityPlacement {
744 type Store: StoreKind;
745 type Canister: CanisterKind;
746}
747
748pub trait EntityKind: EntitySchema + EntityPlacement + Kind + TypeKind {
758 const ENTITY_TAG: EntityTag;
759}
760
761pub trait EntityValue: EntityKey + AuthoredFieldProjection + FieldProjection + Sized {
779 fn id(&self) -> Id<Self>;
780}
781
782pub struct EntityCreateMaterialization<E> {
791 entity: E,
792 authored_slots: Vec<usize>,
793}
794
795impl<E> EntityCreateMaterialization<E> {
796 #[must_use]
798 pub const fn new(entity: E, authored_slots: Vec<usize>) -> Self {
799 Self {
800 entity,
801 authored_slots,
802 }
803 }
804
805 #[must_use]
807 pub fn into_entity(self) -> E {
808 self.entity
809 }
810
811 #[must_use]
813 pub const fn authored_slots(&self) -> &[usize] {
814 self.authored_slots.as_slice()
815 }
816}
817
818pub trait EntityCreateInput: Sized {
827 type Entity: EntityValue;
828
829 fn materialize_create(self)
831 -> Result<EntityCreateMaterialization<Self::Entity>, InternalError>;
832}
833
834pub trait EntityCreateType: EntityValue {
844 type Create: EntityCreateInput<Entity = Self>;
845}
846
847pub trait SingletonEntity: EntityValue {}
849
850pub trait TypeKind:
868 Kind + Clone + DeserializeOwned + Sanitize + Validate + Visitable + PartialEq
869{
870}
871
872impl<T> TypeKind for T where
873 T: Kind + Clone + DeserializeOwned + PartialEq + Sanitize + Validate + Visitable
874{
875}
876
877pub trait FieldTypeMeta {
886 const KIND: FieldKind;
888
889 const STORAGE_DECODE: FieldStorageDecode;
891
892 const NESTED_FIELDS: &'static [FieldModel] = &[];
894}
895
896pub trait PersistedFieldMetaCodec: FieldTypeMeta + Sized {
907 fn encode_persisted_slot_payload_by_meta(
910 &self,
911 field_name: &'static str,
912 ) -> Result<Vec<u8>, InternalError>;
913
914 fn decode_persisted_slot_payload_by_meta(
917 bytes: &[u8],
918 field_name: &'static str,
919 ) -> Result<Self, InternalError>;
920
921 fn encode_persisted_option_slot_payload_by_meta(
924 value: &Option<Self>,
925 field_name: &'static str,
926 ) -> Result<Vec<u8>, InternalError>;
927
928 fn decode_persisted_option_slot_payload_by_meta(
931 bytes: &[u8],
932 field_name: &'static str,
933 ) -> Result<Option<Self>, InternalError>;
934}
935
936pub trait PersistedFieldSlotCodec: Sized {
946 fn encode_persisted_slot(&self, field_name: &'static str) -> Result<Vec<u8>, InternalError>;
949
950 fn decode_persisted_slot(bytes: &[u8], field_name: &'static str)
953 -> Result<Self, InternalError>;
954
955 fn encode_persisted_option_slot(
958 value: &Option<Self>,
959 field_name: &'static str,
960 ) -> Result<Vec<u8>, InternalError>;
961
962 fn decode_persisted_option_slot(
965 bytes: &[u8],
966 field_name: &'static str,
967 ) -> Result<Option<Self>, InternalError>;
968}
969
970impl<T> FieldTypeMeta for Option<T>
971where
972 T: FieldTypeMeta,
973{
974 const KIND: FieldKind = T::KIND;
975 const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
976 const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
977}
978
979impl<T> FieldTypeMeta for Box<T>
980where
981 T: FieldTypeMeta,
982{
983 const KIND: FieldKind = T::KIND;
984 const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
985 const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
986}
987
988impl<T> FieldTypeMeta for Vec<T>
992where
993 T: FieldTypeMeta,
994{
995 const KIND: FieldKind = FieldKind::List(&T::KIND);
996 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
997}
998
999impl<T> FieldTypeMeta for BTreeSet<T>
1000where
1001 T: FieldTypeMeta,
1002{
1003 const KIND: FieldKind = FieldKind::Set(&T::KIND);
1004 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
1005}
1006
1007impl<K, V> FieldTypeMeta for BTreeMap<K, V>
1008where
1009 K: FieldTypeMeta,
1010 V: FieldTypeMeta,
1011{
1012 const KIND: FieldKind = FieldKind::Map {
1013 key: &K::KIND,
1014 value: &V::KIND,
1015 };
1016 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
1017}
1018
1019pub trait Collection {
1032 type Item;
1033
1034 type Iter<'a>: Iterator<Item = &'a Self::Item> + 'a
1036 where
1037 Self: 'a;
1038
1039 fn iter(&self) -> Self::Iter<'_>;
1041
1042 fn len(&self) -> usize;
1044
1045 fn is_empty(&self) -> bool {
1047 self.len() == 0
1048 }
1049}
1050
1051pub trait MapCollection {
1060 type Key;
1061 type Value;
1062
1063 type Iter<'a>: Iterator<Item = (&'a Self::Key, &'a Self::Value)> + 'a
1065 where
1066 Self: 'a;
1067
1068 fn iter(&self) -> Self::Iter<'_>;
1070
1071 fn len(&self) -> usize;
1073
1074 fn is_empty(&self) -> bool {
1076 self.len() == 0
1077 }
1078}
1079
1080impl<T> Collection for Vec<T> {
1081 type Item = T;
1082 type Iter<'a>
1083 = std::slice::Iter<'a, T>
1084 where
1085 Self: 'a;
1086
1087 fn iter(&self) -> Self::Iter<'_> {
1088 self.as_slice().iter()
1089 }
1090
1091 fn len(&self) -> usize {
1092 self.as_slice().len()
1093 }
1094}
1095
1096impl<T> Collection for BTreeSet<T> {
1097 type Item = T;
1098 type Iter<'a>
1099 = std::collections::btree_set::Iter<'a, T>
1100 where
1101 Self: 'a;
1102
1103 fn iter(&self) -> Self::Iter<'_> {
1104 self.iter()
1105 }
1106
1107 fn len(&self) -> usize {
1108 self.len()
1109 }
1110}
1111
1112impl<K, V> MapCollection for BTreeMap<K, V> {
1113 type Key = K;
1114 type Value = V;
1115 type Iter<'a>
1116 = std::collections::btree_map::Iter<'a, K, V>
1117 where
1118 Self: 'a;
1119
1120 fn iter(&self) -> Self::Iter<'_> {
1121 self.iter()
1122 }
1123
1124 fn len(&self) -> usize {
1125 self.len()
1126 }
1127}
1128
1129pub trait AuthoredFieldProjection {
1131 fn get_input_value_by_index(&self, index: usize) -> Option<InputValue>;
1133}
1134
1135pub trait FieldProjection {
1136 fn get_value_by_index(&self, index: usize) -> Option<Value>;
1138}
1139
1140#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1148pub enum RuntimeValueKind {
1149 Atomic,
1151
1152 Structured {
1155 queryable: bool,
1157 },
1158}
1159
1160impl RuntimeValueKind {
1161 #[must_use]
1162 pub const fn is_queryable(self) -> bool {
1163 match self {
1164 Self::Atomic => true,
1165 Self::Structured { queryable } => queryable,
1166 }
1167 }
1168}
1169
1170pub trait RuntimeValueMeta {
1179 fn kind() -> RuntimeValueKind
1180 where
1181 Self: Sized;
1182}
1183
1184pub fn runtime_value_collection_to_value<C>(collection: &C) -> Value
1193where
1194 C: Collection,
1195 C::Item: RuntimeValueEncode,
1196{
1197 Value::List(
1198 collection
1199 .iter()
1200 .map(RuntimeValueEncode::to_value)
1201 .collect(),
1202 )
1203}
1204
1205#[must_use]
1214pub fn runtime_value_vec_from_value<T>(value: &Value) -> Option<Vec<T>>
1215where
1216 T: RuntimeValueDecode,
1217{
1218 let Value::List(values) = value else {
1219 return None;
1220 };
1221
1222 let mut out = Vec::with_capacity(values.len());
1223 for value in values {
1224 out.push(T::from_value(value)?);
1225 }
1226
1227 Some(out)
1228}
1229
1230#[must_use]
1239pub fn runtime_value_btree_set_from_value<T>(value: &Value) -> Option<BTreeSet<T>>
1240where
1241 T: Ord + RuntimeValueDecode,
1242{
1243 let Value::List(values) = value else {
1244 return None;
1245 };
1246
1247 let mut out = BTreeSet::new();
1248 for value in values {
1249 let item = T::from_value(value)?;
1250 if !out.insert(item) {
1251 return None;
1252 }
1253 }
1254
1255 Some(out)
1256}
1257
1258pub fn runtime_value_map_collection_to_value<M>(map: &M, path: &'static str) -> Value
1268where
1269 M: MapCollection,
1270 M::Key: RuntimeValueEncode,
1271 M::Value: RuntimeValueEncode,
1272{
1273 let mut entries: Vec<(Value, Value)> = map
1274 .iter()
1275 .map(|(key, value)| {
1276 (
1277 RuntimeValueEncode::to_value(key),
1278 RuntimeValueEncode::to_value(value),
1279 )
1280 })
1281 .collect();
1282
1283 if let Err(err) = Value::validate_map_entries(entries.as_slice()) {
1284 debug_assert!(false, "invalid map field value for {path}: {err}");
1285 return Value::Map(entries);
1286 }
1287
1288 Value::sort_map_entries_in_place(entries.as_mut_slice());
1289
1290 for i in 1..entries.len() {
1291 let (left_key, _) = &entries[i - 1];
1292 let (right_key, _) = &entries[i];
1293 if Value::canonical_cmp_key(left_key, right_key) == Ordering::Equal {
1294 debug_assert!(
1295 false,
1296 "duplicate map key in {path} after value-surface canonicalization",
1297 );
1298 break;
1299 }
1300 }
1301
1302 Value::Map(entries)
1303}
1304
1305#[must_use]
1314pub fn runtime_value_btree_map_from_value<K, V>(value: &Value) -> Option<BTreeMap<K, V>>
1315where
1316 K: Ord + RuntimeValueDecode,
1317 V: RuntimeValueDecode,
1318{
1319 let Value::Map(entries) = value else {
1320 return None;
1321 };
1322
1323 let normalized = Value::normalize_map_entries(entries.clone()).ok()?;
1324 if normalized.as_slice() != entries.as_slice() {
1325 return None;
1326 }
1327
1328 let mut map = BTreeMap::new();
1329 for (entry_key, entry_value) in normalized {
1330 let key = K::from_value(&entry_key)?;
1331 let value = V::from_value(&entry_value)?;
1332 map.insert(key, value);
1333 }
1334
1335 Some(map)
1336}
1337
1338#[must_use]
1347pub fn runtime_value_from_vec_into<T, I>(entries: Vec<I>) -> Vec<T>
1348where
1349 I: Into<T>,
1350{
1351 entries.into_iter().map(Into::into).collect()
1352}
1353
1354#[must_use]
1363pub fn runtime_value_from_vec_into_btree_set<T, I>(entries: Vec<I>) -> BTreeSet<T>
1364where
1365 I: Into<T>,
1366 T: Ord,
1367{
1368 entries.into_iter().map(Into::into).collect()
1369}
1370
1371#[must_use]
1380pub fn runtime_value_from_vec_into_btree_map<K, V, IK, IV>(entries: Vec<(IK, IV)>) -> BTreeMap<K, V>
1381where
1382 IK: Into<K>,
1383 IV: Into<V>,
1384 K: Ord,
1385{
1386 entries
1387 .into_iter()
1388 .map(|(key, value)| (key.into(), value.into()))
1389 .collect()
1390}
1391
1392#[must_use]
1401pub fn runtime_value_into<T, U>(value: U) -> T
1402where
1403 U: Into<T>,
1404{
1405 value.into()
1406}
1407
1408impl RuntimeValueMeta for &str {
1409 fn kind() -> RuntimeValueKind {
1410 RuntimeValueKind::Atomic
1411 }
1412}
1413
1414impl RuntimeValueEncode for &str {
1415 fn to_value(&self) -> Value {
1416 Value::Text((*self).to_string())
1417 }
1418}
1419
1420impl RuntimeValueDecode for &str {
1421 fn from_value(_value: &Value) -> Option<Self> {
1422 None
1423 }
1424}
1425
1426impl RuntimeValueMeta for String {
1427 fn kind() -> RuntimeValueKind {
1428 RuntimeValueKind::Atomic
1429 }
1430}
1431
1432impl RuntimeValueEncode for String {
1433 fn to_value(&self) -> Value {
1434 Value::Text(self.clone())
1435 }
1436}
1437
1438impl RuntimeValueDecode for String {
1439 fn from_value(value: &Value) -> Option<Self> {
1440 match value {
1441 Value::Text(v) => Some(v.clone()),
1442 _ => None,
1443 }
1444 }
1445}
1446
1447impl<T: RuntimeValueMeta> RuntimeValueMeta for Option<T> {
1448 fn kind() -> RuntimeValueKind {
1449 T::kind()
1450 }
1451}
1452
1453impl<T: RuntimeValueEncode> RuntimeValueEncode for Option<T> {
1454 fn to_value(&self) -> Value {
1455 match self {
1456 Some(v) => v.to_value(),
1457 None => Value::Null,
1458 }
1459 }
1460}
1461
1462impl<T: RuntimeValueDecode> RuntimeValueDecode for Option<T> {
1463 fn from_value(value: &Value) -> Option<Self> {
1464 if matches!(value, Value::Null) {
1465 return Some(None);
1466 }
1467
1468 T::from_value(value).map(Some)
1469 }
1470
1471 fn from_value_with_enum_context(
1472 value: &Value,
1473 context: &dyn RuntimeEnumContext,
1474 ) -> Option<Self> {
1475 if matches!(value, Value::Null) {
1476 return Some(None);
1477 }
1478
1479 T::from_value_with_enum_context(value, context).map(Some)
1480 }
1481}
1482
1483impl<T: RuntimeValueMeta> RuntimeValueMeta for Box<T> {
1484 fn kind() -> RuntimeValueKind {
1485 T::kind()
1486 }
1487}
1488
1489impl<T: RuntimeValueEncode> RuntimeValueEncode for Box<T> {
1490 fn to_value(&self) -> Value {
1491 (**self).to_value()
1492 }
1493}
1494
1495impl<T: RuntimeValueDecode> RuntimeValueDecode for Box<T> {
1496 fn from_value(value: &Value) -> Option<Self> {
1497 T::from_value(value).map(Self::new)
1498 }
1499
1500 fn from_value_with_enum_context(
1501 value: &Value,
1502 context: &dyn RuntimeEnumContext,
1503 ) -> Option<Self> {
1504 T::from_value_with_enum_context(value, context).map(Self::new)
1505 }
1506}
1507
1508impl<T> RuntimeValueMeta for Vec<T> {
1509 fn kind() -> RuntimeValueKind {
1510 RuntimeValueKind::Structured { queryable: true }
1511 }
1512}
1513
1514impl<T: RuntimeValueEncode> RuntimeValueEncode for Vec<T> {
1515 fn to_value(&self) -> Value {
1516 runtime_value_collection_to_value(self)
1517 }
1518}
1519
1520impl<T: RuntimeValueDecode> RuntimeValueDecode for Vec<T> {
1521 fn from_value(value: &Value) -> Option<Self> {
1522 runtime_value_vec_from_value(value)
1523 }
1524
1525 fn from_value_with_enum_context(
1526 value: &Value,
1527 context: &dyn RuntimeEnumContext,
1528 ) -> Option<Self> {
1529 let Value::List(values) = value else {
1530 return None;
1531 };
1532 values
1533 .iter()
1534 .map(|value| T::from_value_with_enum_context(value, context))
1535 .collect()
1536 }
1537}
1538
1539impl<T> RuntimeValueMeta for BTreeSet<T>
1540where
1541 T: Ord,
1542{
1543 fn kind() -> RuntimeValueKind {
1544 RuntimeValueKind::Structured { queryable: true }
1545 }
1546}
1547
1548impl<T> RuntimeValueEncode for BTreeSet<T>
1549where
1550 T: Ord + RuntimeValueEncode,
1551{
1552 fn to_value(&self) -> Value {
1553 runtime_value_collection_to_value(self)
1554 }
1555}
1556
1557impl<T> RuntimeValueDecode for BTreeSet<T>
1558where
1559 T: Ord + RuntimeValueDecode,
1560{
1561 fn from_value(value: &Value) -> Option<Self> {
1562 runtime_value_btree_set_from_value(value)
1563 }
1564
1565 fn from_value_with_enum_context(
1566 value: &Value,
1567 context: &dyn RuntimeEnumContext,
1568 ) -> Option<Self> {
1569 let Value::List(values) = value else {
1570 return None;
1571 };
1572 values
1573 .iter()
1574 .map(|value| T::from_value_with_enum_context(value, context))
1575 .collect()
1576 }
1577}
1578
1579impl<K, V> RuntimeValueMeta for BTreeMap<K, V>
1580where
1581 K: Ord,
1582{
1583 fn kind() -> RuntimeValueKind {
1584 RuntimeValueKind::Structured { queryable: true }
1585 }
1586}
1587
1588impl<K, V> RuntimeValueEncode for BTreeMap<K, V>
1589where
1590 K: Ord + RuntimeValueEncode,
1591 V: RuntimeValueEncode,
1592{
1593 fn to_value(&self) -> Value {
1594 runtime_value_map_collection_to_value(self, std::any::type_name::<Self>())
1595 }
1596}
1597
1598impl<K, V> RuntimeValueDecode for BTreeMap<K, V>
1599where
1600 K: Ord + RuntimeValueDecode,
1601 V: RuntimeValueDecode,
1602{
1603 fn from_value(value: &Value) -> Option<Self> {
1604 runtime_value_btree_map_from_value(value)
1605 }
1606
1607 fn from_value_with_enum_context(
1608 value: &Value,
1609 context: &dyn RuntimeEnumContext,
1610 ) -> Option<Self> {
1611 let Value::Map(entries) = value else {
1612 return None;
1613 };
1614 entries
1615 .iter()
1616 .map(|(key, value)| {
1617 Some((
1618 K::from_value_with_enum_context(key, context)?,
1619 V::from_value_with_enum_context(value, context)?,
1620 ))
1621 })
1622 .collect()
1623 }
1624}
1625
1626#[macro_export]
1628macro_rules! impl_runtime_value {
1629 ( $( $type:ty => $variant:ident ),* $(,)? ) => {
1630 $(
1631 impl RuntimeValueMeta for $type {
1632 fn kind() -> RuntimeValueKind {
1633 RuntimeValueKind::Atomic
1634 }
1635 }
1636
1637 impl RuntimeValueEncode for $type {
1638 fn to_value(&self) -> Value {
1639 Value::$variant((*self).into())
1640 }
1641 }
1642
1643 impl RuntimeValueDecode for $type {
1644 fn from_value(value: &Value) -> Option<Self> {
1645 match value {
1646 Value::$variant(v) => (*v).try_into().ok(),
1647 _ => None,
1648 }
1649 }
1650 }
1651 )*
1652 };
1653}
1654
1655impl_runtime_value!(
1656 i8 => Int64,
1657 i16 => Int64,
1658 i32 => Int64,
1659 i64 => Int64,
1660 i128 => Int128,
1661 u8 => Nat64,
1662 u16 => Nat64,
1663 u32 => Nat64,
1664 u64 => Nat64,
1665 u128 => Nat128,
1666 bool => Bool,
1667);
1668
1669pub trait Inner<T> {
1680 fn inner(&self) -> &T;
1681 fn into_inner(self) -> T;
1682}
1683
1684pub trait Repr {
1691 type Inner;
1692
1693 fn repr(&self) -> Self::Inner;
1694 fn from_repr(inner: Self::Inner) -> Self;
1695}
1696
1697pub trait Sanitizer<T> {
1708 fn sanitize(&self, value: &mut T) -> Result<(), String>;
1709
1710 fn sanitize_with_context(
1711 &self,
1712 value: &mut T,
1713 ctx: &mut dyn VisitorContext,
1714 ) -> Result<(), String> {
1715 let _ = ctx;
1716
1717 self.sanitize(value)
1718 }
1719}
1720
1721pub trait Validator<T: ?Sized> {
1728 fn validate(&self, value: &T, ctx: &mut dyn VisitorContext);
1729}