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::{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 std::fmt::Display for PrimaryKeyEncodeError {
245 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
246 f.write_str("primary key encode error")
247 }
248}
249
250impl std::error::Error for PrimaryKeyEncodeError {}
251
252impl From<CompositePrimaryKeyValueError> for PrimaryKeyEncodeError {
253 fn from(err: CompositePrimaryKeyValueError) -> Self {
254 match err {
255 CompositePrimaryKeyValueError::TooFewComponents { count, min } => {
256 Self::TooFewComponents { count, min }
257 }
258 CompositePrimaryKeyValueError::TooManyComponents { count, max } => {
259 Self::TooManyComponents { count, max }
260 }
261 CompositePrimaryKeyValueError::UnitComponent { index } => Self::UnitComponent { index },
262 }
263 }
264}
265
266impl From<PrimaryKeyEncodeError> for InternalError {
267 fn from(_err: PrimaryKeyEncodeError) -> Self {
268 Self::serialize_unsupported("primary key encode error")
269 }
270}
271
272pub trait PrimaryKeyCodec {
281 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError>;
282}
283
284pub trait PrimaryKeyDecode: Sized {
294 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError>;
295}
296
297fn primary_key_variant_decode_failed(
298 _type_name: &'static str,
299 _key: &PrimaryKeyValue,
300 _expected: &'static str,
301) -> InternalError {
302 InternalError::store_corruption()
303}
304
305fn primary_key_range_decode_failed(
306 _type_name: &'static str,
307 _key: &PrimaryKeyValue,
308) -> InternalError {
309 InternalError::store_corruption()
310}
311
312macro_rules! impl_primary_key_codec_signed {
313 ($($ty:ty),* $(,)?) => {
314 $(
315 impl PrimaryKeyCodec for $ty {
316 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
317 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Int64(i64::from(*self))))
318 }
319 }
320 )*
321 };
322}
323
324macro_rules! impl_primary_key_codec_unsigned {
325 ($($ty:ty),* $(,)?) => {
326 $(
327 impl PrimaryKeyCodec for $ty {
328 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
329 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Nat64(u64::from(*self))))
330 }
331 }
332 )*
333 };
334}
335
336impl<T> KeyValueCodec for T
337where
338 T: RuntimeValueDecode + RuntimeValueEncode,
339{
340 fn to_key_value(&self) -> Value {
341 self.to_value()
342 }
343
344 fn from_key_value(value: &Value) -> Option<Self> {
345 Self::from_value(value)
346 }
347}
348
349impl_primary_key_codec_signed!(i8, i16, i32, i64);
350impl_primary_key_codec_unsigned!(u8, u16, u32, u64);
351
352impl PrimaryKeyCodec for i128 {
353 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
354 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Int128(*self)))
355 }
356}
357
358impl PrimaryKeyCodec for u128 {
359 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
360 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Nat128(*self)))
361 }
362}
363
364macro_rules! impl_primary_key_decode_signed {
365 ($($ty:ty),* $(,)?) => {
366 $(
367 impl PrimaryKeyDecode for $ty {
368 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
369 let PrimaryKeyValue::Scalar(PrimaryKeyComponent::Int64(value)) = *key else {
370 return Err(primary_key_variant_decode_failed(
371 ::std::any::type_name::<Self>(),
372 key,
373 "PrimaryKeyComponent::Int64",
374 ));
375 };
376
377 Self::try_from(value).map_err(|_| {
378 primary_key_range_decode_failed(::std::any::type_name::<Self>(), key)
379 })
380 }
381 }
382 )*
383 };
384}
385
386macro_rules! impl_primary_key_decode_unsigned {
387 ($($ty:ty),* $(,)?) => {
388 $(
389 impl PrimaryKeyDecode for $ty {
390 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
391 let PrimaryKeyValue::Scalar(PrimaryKeyComponent::Nat64(value)) = *key else {
392 return Err(primary_key_variant_decode_failed(
393 ::std::any::type_name::<Self>(),
394 key,
395 "PrimaryKeyComponent::Nat64",
396 ));
397 };
398
399 Self::try_from(value).map_err(|_| {
400 primary_key_range_decode_failed(::std::any::type_name::<Self>(), key)
401 })
402 }
403 }
404 )*
405 };
406}
407
408impl_primary_key_decode_signed!(i8, i16, i32, i64);
409impl_primary_key_decode_unsigned!(u8, u16, u32, u64);
410
411impl PrimaryKeyDecode for i128 {
412 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
413 match *key {
414 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Int128(value)) => Ok(value),
415 _ => Err(primary_key_variant_decode_failed(
416 ::std::any::type_name::<Self>(),
417 key,
418 "PrimaryKeyComponent::Int128",
419 )),
420 }
421 }
422}
423
424impl PrimaryKeyDecode for u128 {
425 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
426 match *key {
427 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Nat128(value)) => Ok(value),
428 _ => Err(primary_key_variant_decode_failed(
429 ::std::any::type_name::<Self>(),
430 key,
431 "PrimaryKeyComponent::Nat128",
432 )),
433 }
434 }
435}
436
437impl PrimaryKeyCodec for crate::types::Principal {
438 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
439 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Principal(
440 *self,
441 )))
442 }
443}
444
445impl PrimaryKeyDecode for crate::types::Principal {
446 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
447 match *key {
448 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Principal(value)) => Ok(value),
449 _ => Err(primary_key_variant_decode_failed(
450 ::std::any::type_name::<Self>(),
451 key,
452 "PrimaryKeyComponent::Principal",
453 )),
454 }
455 }
456}
457
458impl PrimaryKeyCodec for crate::types::Subaccount {
459 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
460 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Subaccount(
461 *self,
462 )))
463 }
464}
465
466impl PrimaryKeyDecode for crate::types::Subaccount {
467 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
468 match *key {
469 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Subaccount(value)) => Ok(value),
470 _ => Err(primary_key_variant_decode_failed(
471 ::std::any::type_name::<Self>(),
472 key,
473 "PrimaryKeyComponent::Subaccount",
474 )),
475 }
476 }
477}
478
479impl PrimaryKeyCodec for crate::types::Account {
480 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
481 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Account(*self)))
482 }
483}
484
485impl PrimaryKeyDecode for crate::types::Account {
486 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
487 match *key {
488 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Account(value)) => Ok(value),
489 _ => Err(primary_key_variant_decode_failed(
490 ::std::any::type_name::<Self>(),
491 key,
492 "PrimaryKeyComponent::Account",
493 )),
494 }
495 }
496}
497
498impl PrimaryKeyCodec for crate::types::Timestamp {
499 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
500 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Timestamp(
501 *self,
502 )))
503 }
504}
505
506impl PrimaryKeyDecode for crate::types::Timestamp {
507 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
508 match *key {
509 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Timestamp(value)) => Ok(value),
510 _ => Err(primary_key_variant_decode_failed(
511 ::std::any::type_name::<Self>(),
512 key,
513 "PrimaryKeyComponent::Timestamp",
514 )),
515 }
516 }
517}
518
519impl PrimaryKeyCodec for crate::types::Ulid {
520 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
521 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Ulid(*self)))
522 }
523}
524
525impl PrimaryKeyDecode for crate::types::Ulid {
526 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
527 match *key {
528 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Ulid(value)) => Ok(value),
529 _ => Err(primary_key_variant_decode_failed(
530 ::std::any::type_name::<Self>(),
531 key,
532 "PrimaryKeyComponent::Ulid",
533 )),
534 }
535 }
536}
537
538impl PrimaryKeyCodec for () {
539 fn to_primary_key_value(&self) -> Result<PrimaryKeyValue, PrimaryKeyEncodeError> {
540 Ok(PrimaryKeyValue::Scalar(PrimaryKeyComponent::Unit))
541 }
542}
543
544impl PrimaryKeyDecode for () {
545 fn from_primary_key_value(key: &PrimaryKeyValue) -> Result<Self, InternalError> {
546 match *key {
547 PrimaryKeyValue::Scalar(PrimaryKeyComponent::Unit) => Ok(()),
548 _ => Err(primary_key_variant_decode_failed(
549 ::std::any::type_name::<Self>(),
550 key,
551 "PrimaryKeyComponent::Unit",
552 )),
553 }
554 }
555}
556
557pub trait RuntimeValueEncode {
569 fn to_value(&self) -> Value;
570}
571
572pub trait RuntimeValueDecode {
583 #[must_use]
584 fn from_value(value: &Value) -> Option<Self>
585 where
586 Self: Sized;
587}
588
589pub fn runtime_value_to_value<T>(value: &T) -> Value
598where
599 T: ?Sized + RuntimeValueEncode,
600{
601 value.to_value()
602}
603
604#[must_use]
613pub fn runtime_value_from_value<T>(value: &Value) -> Option<T>
614where
615 T: RuntimeValueDecode,
616{
617 T::from_value(value)
618}
619
620pub trait PersistedByKindCodec: Sized {
630 fn encode_persisted_slot_payload_by_kind(
632 &self,
633 kind: FieldKind,
634 field_name: &'static str,
635 ) -> Result<Vec<u8>, InternalError>;
636
637 fn decode_persisted_option_slot_payload_by_kind(
641 bytes: &[u8],
642 kind: FieldKind,
643 field_name: &'static str,
644 ) -> Result<Option<Self>, InternalError>;
645}
646
647pub trait PersistedStructuredFieldCodec {
659 fn encode_persisted_structured_payload(&self) -> Result<Vec<u8>, InternalError>;
661
662 fn decode_persisted_structured_payload(bytes: &[u8]) -> Result<Self, InternalError>
664 where
665 Self: Sized;
666}
667
668pub trait EntitySchema: EntityKey {
679 const NAME: &'static str;
680 const MODEL: &'static EntityModel;
681}
682
683pub trait EntityPlacement {
697 type Store: StoreKind;
698 type Canister: CanisterKind;
699}
700
701pub trait EntityKind: EntitySchema + EntityPlacement + Kind + TypeKind {
711 const ENTITY_TAG: EntityTag;
712}
713
714pub trait EntityValue: EntityKey + FieldProjection + Sized {
732 fn id(&self) -> Id<Self>;
733}
734
735pub struct EntityCreateMaterialization<E> {
744 entity: E,
745 authored_slots: Vec<usize>,
746}
747
748impl<E> EntityCreateMaterialization<E> {
749 #[must_use]
751 pub const fn new(entity: E, authored_slots: Vec<usize>) -> Self {
752 Self {
753 entity,
754 authored_slots,
755 }
756 }
757
758 #[must_use]
760 pub fn into_entity(self) -> E {
761 self.entity
762 }
763
764 #[must_use]
766 pub const fn authored_slots(&self) -> &[usize] {
767 self.authored_slots.as_slice()
768 }
769}
770
771pub trait EntityCreateInput: Sized {
780 type Entity: EntityValue;
781
782 fn materialize_create(self)
784 -> Result<EntityCreateMaterialization<Self::Entity>, InternalError>;
785}
786
787pub trait EntityCreateType: EntityValue {
797 type Create: EntityCreateInput<Entity = Self>;
798}
799
800pub trait SingletonEntity: EntityValue {}
802
803pub trait TypeKind:
821 Kind + Clone + DeserializeOwned + Sanitize + Validate + Visitable + PartialEq
822{
823}
824
825impl<T> TypeKind for T where
826 T: Kind + Clone + DeserializeOwned + PartialEq + Sanitize + Validate + Visitable
827{
828}
829
830pub trait FieldTypeMeta {
839 const KIND: FieldKind;
841
842 const STORAGE_DECODE: FieldStorageDecode;
844
845 const NESTED_FIELDS: &'static [FieldModel] = &[];
847}
848
849pub trait PersistedFieldMetaCodec: FieldTypeMeta + Sized {
860 fn encode_persisted_slot_payload_by_meta(
863 &self,
864 field_name: &'static str,
865 ) -> Result<Vec<u8>, InternalError>;
866
867 fn decode_persisted_slot_payload_by_meta(
870 bytes: &[u8],
871 field_name: &'static str,
872 ) -> Result<Self, InternalError>;
873
874 fn encode_persisted_option_slot_payload_by_meta(
877 value: &Option<Self>,
878 field_name: &'static str,
879 ) -> Result<Vec<u8>, InternalError>;
880
881 fn decode_persisted_option_slot_payload_by_meta(
884 bytes: &[u8],
885 field_name: &'static str,
886 ) -> Result<Option<Self>, InternalError>;
887}
888
889pub trait PersistedFieldSlotCodec: Sized {
899 fn encode_persisted_slot(&self, field_name: &'static str) -> Result<Vec<u8>, InternalError>;
902
903 fn decode_persisted_slot(bytes: &[u8], field_name: &'static str)
906 -> Result<Self, InternalError>;
907
908 fn encode_persisted_option_slot(
911 value: &Option<Self>,
912 field_name: &'static str,
913 ) -> Result<Vec<u8>, InternalError>;
914
915 fn decode_persisted_option_slot(
918 bytes: &[u8],
919 field_name: &'static str,
920 ) -> Result<Option<Self>, InternalError>;
921}
922
923impl<T> FieldTypeMeta for Option<T>
924where
925 T: FieldTypeMeta,
926{
927 const KIND: FieldKind = T::KIND;
928 const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
929 const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
930}
931
932impl<T> FieldTypeMeta for Box<T>
933where
934 T: FieldTypeMeta,
935{
936 const KIND: FieldKind = T::KIND;
937 const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
938 const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
939}
940
941impl<T> FieldTypeMeta for Vec<T>
945where
946 T: FieldTypeMeta,
947{
948 const KIND: FieldKind = FieldKind::List(&T::KIND);
949 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
950}
951
952impl<T> FieldTypeMeta for BTreeSet<T>
953where
954 T: FieldTypeMeta,
955{
956 const KIND: FieldKind = FieldKind::Set(&T::KIND);
957 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
958}
959
960impl<K, V> FieldTypeMeta for BTreeMap<K, V>
961where
962 K: FieldTypeMeta,
963 V: FieldTypeMeta,
964{
965 const KIND: FieldKind = FieldKind::Map {
966 key: &K::KIND,
967 value: &V::KIND,
968 };
969 const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
970}
971
972pub trait Collection {
985 type Item;
986
987 type Iter<'a>: Iterator<Item = &'a Self::Item> + 'a
989 where
990 Self: 'a;
991
992 fn iter(&self) -> Self::Iter<'_>;
994
995 fn len(&self) -> usize;
997
998 fn is_empty(&self) -> bool {
1000 self.len() == 0
1001 }
1002}
1003
1004pub trait MapCollection {
1013 type Key;
1014 type Value;
1015
1016 type Iter<'a>: Iterator<Item = (&'a Self::Key, &'a Self::Value)> + 'a
1018 where
1019 Self: 'a;
1020
1021 fn iter(&self) -> Self::Iter<'_>;
1023
1024 fn len(&self) -> usize;
1026
1027 fn is_empty(&self) -> bool {
1029 self.len() == 0
1030 }
1031}
1032
1033impl<T> Collection for Vec<T> {
1034 type Item = T;
1035 type Iter<'a>
1036 = std::slice::Iter<'a, T>
1037 where
1038 Self: 'a;
1039
1040 fn iter(&self) -> Self::Iter<'_> {
1041 self.as_slice().iter()
1042 }
1043
1044 fn len(&self) -> usize {
1045 self.as_slice().len()
1046 }
1047}
1048
1049impl<T> Collection for BTreeSet<T> {
1050 type Item = T;
1051 type Iter<'a>
1052 = std::collections::btree_set::Iter<'a, T>
1053 where
1054 Self: 'a;
1055
1056 fn iter(&self) -> Self::Iter<'_> {
1057 self.iter()
1058 }
1059
1060 fn len(&self) -> usize {
1061 self.len()
1062 }
1063}
1064
1065impl<K, V> MapCollection for BTreeMap<K, V> {
1066 type Key = K;
1067 type Value = V;
1068 type Iter<'a>
1069 = std::collections::btree_map::Iter<'a, K, V>
1070 where
1071 Self: 'a;
1072
1073 fn iter(&self) -> Self::Iter<'_> {
1074 self.iter()
1075 }
1076
1077 fn len(&self) -> usize {
1078 self.len()
1079 }
1080}
1081
1082pub trait EnumValue {
1083 fn to_value_enum(&self) -> ValueEnum;
1084}
1085
1086pub trait FieldProjection {
1087 fn get_value_by_index(&self, index: usize) -> Option<Value>;
1089}
1090
1091#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1099pub enum RuntimeValueKind {
1100 Atomic,
1102
1103 Structured {
1106 queryable: bool,
1108 },
1109}
1110
1111impl RuntimeValueKind {
1112 #[must_use]
1113 pub const fn is_queryable(self) -> bool {
1114 match self {
1115 Self::Atomic => true,
1116 Self::Structured { queryable } => queryable,
1117 }
1118 }
1119}
1120
1121pub trait RuntimeValueMeta {
1130 fn kind() -> RuntimeValueKind
1131 where
1132 Self: Sized;
1133}
1134
1135pub fn runtime_value_collection_to_value<C>(collection: &C) -> Value
1144where
1145 C: Collection,
1146 C::Item: RuntimeValueEncode,
1147{
1148 Value::List(
1149 collection
1150 .iter()
1151 .map(RuntimeValueEncode::to_value)
1152 .collect(),
1153 )
1154}
1155
1156#[must_use]
1165pub fn runtime_value_vec_from_value<T>(value: &Value) -> Option<Vec<T>>
1166where
1167 T: RuntimeValueDecode,
1168{
1169 let Value::List(values) = value else {
1170 return None;
1171 };
1172
1173 let mut out = Vec::with_capacity(values.len());
1174 for value in values {
1175 out.push(T::from_value(value)?);
1176 }
1177
1178 Some(out)
1179}
1180
1181#[must_use]
1190pub fn runtime_value_btree_set_from_value<T>(value: &Value) -> Option<BTreeSet<T>>
1191where
1192 T: Ord + RuntimeValueDecode,
1193{
1194 let Value::List(values) = value else {
1195 return None;
1196 };
1197
1198 let mut out = BTreeSet::new();
1199 for value in values {
1200 let item = T::from_value(value)?;
1201 if !out.insert(item) {
1202 return None;
1203 }
1204 }
1205
1206 Some(out)
1207}
1208
1209pub fn runtime_value_map_collection_to_value<M>(map: &M, path: &'static str) -> Value
1219where
1220 M: MapCollection,
1221 M::Key: RuntimeValueEncode,
1222 M::Value: RuntimeValueEncode,
1223{
1224 let mut entries: Vec<(Value, Value)> = map
1225 .iter()
1226 .map(|(key, value)| {
1227 (
1228 RuntimeValueEncode::to_value(key),
1229 RuntimeValueEncode::to_value(value),
1230 )
1231 })
1232 .collect();
1233
1234 if let Err(err) = Value::validate_map_entries(entries.as_slice()) {
1235 debug_assert!(false, "invalid map field value for {path}: {err}");
1236 return Value::Map(entries);
1237 }
1238
1239 Value::sort_map_entries_in_place(entries.as_mut_slice());
1240
1241 for i in 1..entries.len() {
1242 let (left_key, _) = &entries[i - 1];
1243 let (right_key, _) = &entries[i];
1244 if Value::canonical_cmp_key(left_key, right_key) == Ordering::Equal {
1245 debug_assert!(
1246 false,
1247 "duplicate map key in {path} after value-surface canonicalization",
1248 );
1249 break;
1250 }
1251 }
1252
1253 Value::Map(entries)
1254}
1255
1256#[must_use]
1265pub fn runtime_value_btree_map_from_value<K, V>(value: &Value) -> Option<BTreeMap<K, V>>
1266where
1267 K: Ord + RuntimeValueDecode,
1268 V: RuntimeValueDecode,
1269{
1270 let Value::Map(entries) = value else {
1271 return None;
1272 };
1273
1274 let normalized = Value::normalize_map_entries(entries.clone()).ok()?;
1275 if normalized.as_slice() != entries.as_slice() {
1276 return None;
1277 }
1278
1279 let mut map = BTreeMap::new();
1280 for (entry_key, entry_value) in normalized {
1281 let key = K::from_value(&entry_key)?;
1282 let value = V::from_value(&entry_value)?;
1283 map.insert(key, value);
1284 }
1285
1286 Some(map)
1287}
1288
1289#[must_use]
1298pub fn runtime_value_from_vec_into<T, I>(entries: Vec<I>) -> Vec<T>
1299where
1300 I: Into<T>,
1301{
1302 entries.into_iter().map(Into::into).collect()
1303}
1304
1305#[must_use]
1314pub fn runtime_value_from_vec_into_btree_set<T, I>(entries: Vec<I>) -> BTreeSet<T>
1315where
1316 I: Into<T>,
1317 T: Ord,
1318{
1319 entries.into_iter().map(Into::into).collect()
1320}
1321
1322#[must_use]
1331pub fn runtime_value_from_vec_into_btree_map<K, V, IK, IV>(entries: Vec<(IK, IV)>) -> BTreeMap<K, V>
1332where
1333 IK: Into<K>,
1334 IV: Into<V>,
1335 K: Ord,
1336{
1337 entries
1338 .into_iter()
1339 .map(|(key, value)| (key.into(), value.into()))
1340 .collect()
1341}
1342
1343#[must_use]
1352pub fn runtime_value_into<T, U>(value: U) -> T
1353where
1354 U: Into<T>,
1355{
1356 value.into()
1357}
1358
1359impl RuntimeValueMeta for &str {
1360 fn kind() -> RuntimeValueKind {
1361 RuntimeValueKind::Atomic
1362 }
1363}
1364
1365impl RuntimeValueEncode for &str {
1366 fn to_value(&self) -> Value {
1367 Value::Text((*self).to_string())
1368 }
1369}
1370
1371impl RuntimeValueDecode for &str {
1372 fn from_value(_value: &Value) -> Option<Self> {
1373 None
1374 }
1375}
1376
1377impl RuntimeValueMeta for String {
1378 fn kind() -> RuntimeValueKind {
1379 RuntimeValueKind::Atomic
1380 }
1381}
1382
1383impl RuntimeValueEncode for String {
1384 fn to_value(&self) -> Value {
1385 Value::Text(self.clone())
1386 }
1387}
1388
1389impl RuntimeValueDecode for String {
1390 fn from_value(value: &Value) -> Option<Self> {
1391 match value {
1392 Value::Text(v) => Some(v.clone()),
1393 _ => None,
1394 }
1395 }
1396}
1397
1398impl<T: RuntimeValueMeta> RuntimeValueMeta for Option<T> {
1399 fn kind() -> RuntimeValueKind {
1400 T::kind()
1401 }
1402}
1403
1404impl<T: RuntimeValueEncode> RuntimeValueEncode for Option<T> {
1405 fn to_value(&self) -> Value {
1406 match self {
1407 Some(v) => v.to_value(),
1408 None => Value::Null,
1409 }
1410 }
1411}
1412
1413impl<T: RuntimeValueDecode> RuntimeValueDecode for Option<T> {
1414 fn from_value(value: &Value) -> Option<Self> {
1415 if matches!(value, Value::Null) {
1416 return Some(None);
1417 }
1418
1419 T::from_value(value).map(Some)
1420 }
1421}
1422
1423impl<T: RuntimeValueMeta> RuntimeValueMeta for Box<T> {
1424 fn kind() -> RuntimeValueKind {
1425 T::kind()
1426 }
1427}
1428
1429impl<T: RuntimeValueEncode> RuntimeValueEncode for Box<T> {
1430 fn to_value(&self) -> Value {
1431 (**self).to_value()
1432 }
1433}
1434
1435impl<T: RuntimeValueDecode> RuntimeValueDecode for Box<T> {
1436 fn from_value(value: &Value) -> Option<Self> {
1437 T::from_value(value).map(Self::new)
1438 }
1439}
1440
1441impl<T> RuntimeValueMeta for Vec<T> {
1442 fn kind() -> RuntimeValueKind {
1443 RuntimeValueKind::Structured { queryable: true }
1444 }
1445}
1446
1447impl<T: RuntimeValueEncode> RuntimeValueEncode for Vec<T> {
1448 fn to_value(&self) -> Value {
1449 runtime_value_collection_to_value(self)
1450 }
1451}
1452
1453impl<T: RuntimeValueDecode> RuntimeValueDecode for Vec<T> {
1454 fn from_value(value: &Value) -> Option<Self> {
1455 runtime_value_vec_from_value(value)
1456 }
1457}
1458
1459impl<T> RuntimeValueMeta for BTreeSet<T>
1460where
1461 T: Ord,
1462{
1463 fn kind() -> RuntimeValueKind {
1464 RuntimeValueKind::Structured { queryable: true }
1465 }
1466}
1467
1468impl<T> RuntimeValueEncode for BTreeSet<T>
1469where
1470 T: Ord + RuntimeValueEncode,
1471{
1472 fn to_value(&self) -> Value {
1473 runtime_value_collection_to_value(self)
1474 }
1475}
1476
1477impl<T> RuntimeValueDecode for BTreeSet<T>
1478where
1479 T: Ord + RuntimeValueDecode,
1480{
1481 fn from_value(value: &Value) -> Option<Self> {
1482 runtime_value_btree_set_from_value(value)
1483 }
1484}
1485
1486impl<K, V> RuntimeValueMeta for BTreeMap<K, V>
1487where
1488 K: Ord,
1489{
1490 fn kind() -> RuntimeValueKind {
1491 RuntimeValueKind::Structured { queryable: true }
1492 }
1493}
1494
1495impl<K, V> RuntimeValueEncode for BTreeMap<K, V>
1496where
1497 K: Ord + RuntimeValueEncode,
1498 V: RuntimeValueEncode,
1499{
1500 fn to_value(&self) -> Value {
1501 runtime_value_map_collection_to_value(self, std::any::type_name::<Self>())
1502 }
1503}
1504
1505impl<K, V> RuntimeValueDecode for BTreeMap<K, V>
1506where
1507 K: Ord + RuntimeValueDecode,
1508 V: RuntimeValueDecode,
1509{
1510 fn from_value(value: &Value) -> Option<Self> {
1511 runtime_value_btree_map_from_value(value)
1512 }
1513}
1514
1515#[macro_export]
1517macro_rules! impl_runtime_value {
1518 ( $( $type:ty => $variant:ident ),* $(,)? ) => {
1519 $(
1520 impl RuntimeValueMeta for $type {
1521 fn kind() -> RuntimeValueKind {
1522 RuntimeValueKind::Atomic
1523 }
1524 }
1525
1526 impl RuntimeValueEncode for $type {
1527 fn to_value(&self) -> Value {
1528 Value::$variant((*self).into())
1529 }
1530 }
1531
1532 impl RuntimeValueDecode for $type {
1533 fn from_value(value: &Value) -> Option<Self> {
1534 match value {
1535 Value::$variant(v) => (*v).try_into().ok(),
1536 _ => None,
1537 }
1538 }
1539 }
1540 )*
1541 };
1542}
1543
1544impl_runtime_value!(
1545 i8 => Int64,
1546 i16 => Int64,
1547 i32 => Int64,
1548 i64 => Int64,
1549 i128 => Int128,
1550 u8 => Nat64,
1551 u16 => Nat64,
1552 u32 => Nat64,
1553 u64 => Nat64,
1554 u128 => Nat128,
1555 bool => Bool,
1556);
1557
1558pub trait Inner<T> {
1569 fn inner(&self) -> &T;
1570 fn into_inner(self) -> T;
1571}
1572
1573pub trait Repr {
1580 type Inner;
1581
1582 fn repr(&self) -> Self::Inner;
1583 fn from_repr(inner: Self::Inner) -> Self;
1584}
1585
1586pub trait Sanitizer<T> {
1597 fn sanitize(&self, value: &mut T) -> Result<(), String>;
1598
1599 fn sanitize_with_context(
1600 &self,
1601 value: &mut T,
1602 ctx: &mut dyn VisitorContext,
1603 ) -> Result<(), String> {
1604 let _ = ctx;
1605
1606 self.sanitize(value)
1607 }
1608}
1609
1610pub trait Validator<T: ?Sized> {
1617 fn validate(&self, value: &T, ctx: &mut dyn VisitorContext);
1618}