use crate::{
model::field::{FieldKind, FieldModel, FieldStorageDecode},
value::{InputValue, Value},
visitor::Visitable,
};
use serde::de::DeserializeOwned;
use std::collections::{BTreeMap, BTreeSet};
pub trait Path {
const PATH: &'static str;
}
pub trait Kind: Path + 'static {}
impl<T> Kind for T where T: Path + 'static {}
pub trait CanisterKind: Kind {
const COMMIT_MEMORY_ID: u8;
const COMMIT_STABLE_KEY: &'static str;
}
pub trait StoreKind: Kind {
type Canister: CanisterKind;
}
pub trait TypeKind: Kind + Clone + DeserializeOwned + Visitable + PartialEq {}
impl<T> TypeKind for T where T: Kind + Clone + DeserializeOwned + PartialEq + Visitable {}
pub trait FieldTypeMeta {
const KIND: FieldKind;
const STORAGE_DECODE: FieldStorageDecode;
const NESTED_FIELDS: &'static [FieldModel] = &[];
}
impl<T> FieldTypeMeta for Option<T>
where
T: FieldTypeMeta,
{
const KIND: FieldKind = T::KIND;
const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
}
impl<T> FieldTypeMeta for Box<T>
where
T: FieldTypeMeta,
{
const KIND: FieldKind = T::KIND;
const STORAGE_DECODE: FieldStorageDecode = T::STORAGE_DECODE;
const NESTED_FIELDS: &'static [FieldModel] = T::NESTED_FIELDS;
}
impl<T> FieldTypeMeta for Vec<T>
where
T: FieldTypeMeta,
{
const KIND: FieldKind = FieldKind::List(&T::KIND);
const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
}
impl<T> FieldTypeMeta for BTreeSet<T>
where
T: FieldTypeMeta,
{
const KIND: FieldKind = FieldKind::Set(&T::KIND);
const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
}
impl<K, V> FieldTypeMeta for BTreeMap<K, V>
where
K: FieldTypeMeta,
V: FieldTypeMeta,
{
const KIND: FieldKind = FieldKind::Map {
key: &K::KIND,
value: &V::KIND,
};
const STORAGE_DECODE: FieldStorageDecode = FieldStorageDecode::Value;
}
pub trait AuthoredFieldProjection {
fn get_input_value_by_index(&self, index: usize) -> Option<InputValue>;
}
pub trait FieldProjection {
fn get_value_by_index(&self, index: usize) -> Option<Value>;
}
pub trait Inner<T> {
fn inner(&self) -> &T;
fn into_inner(self) -> T;
}
pub trait Repr {
type Inner;
fn repr(&self) -> Self::Inner;
fn from_repr(inner: Self::Inner) -> Self;
}