use crate::{
db::EntityKey,
model::EntityModel,
traits::{AuthoredFieldProjection, CanisterKind, FieldProjection, StoreKind, TypeKind},
types::{EntityTag, Id},
value::InputValue,
};
pub trait EntityDeclaration: EntityKey {
const NAME: &'static str;
const MODEL: &'static EntityModel;
}
pub trait EntityPlacement {
type Store: StoreKind<Canister = Self::Canister>;
type Canister: CanisterKind;
}
pub trait EntityKind: EntityDeclaration + EntityPlacement + TypeKind {
const ENTITY_TAG: EntityTag;
}
pub trait EntityValue: EntityKey + AuthoredFieldProjection + FieldProjection + Sized {
fn id(&self) -> Id<Self>;
}
pub struct EntityCreateFieldInput {
slot: usize,
value: InputValue,
}
impl EntityCreateFieldInput {
#[must_use]
pub const fn new(slot: usize, value: InputValue) -> Self {
Self { slot, value }
}
#[must_use]
pub const fn slot(&self) -> usize {
self.slot
}
#[must_use]
pub fn into_value(self) -> InputValue {
self.value
}
}
pub trait EntityCreateInput: Sized {
type Entity: EntityValue;
fn into_authored_fields(self) -> Vec<EntityCreateFieldInput>;
}
pub trait EntityCreateType: EntityValue {
type Create: EntityCreateInput<Entity = Self>;
}
mod singleton {
pub trait Key {}
impl Key for () {}
impl Key for crate::types::Unit {}
pub trait Sealed {}
impl<E> Sealed for E
where
E: super::EntityValue,
E::Key: Key,
{
}
}
pub trait SingletonEntity: EntityValue + singleton::Sealed {}
impl<E> SingletonEntity for E where E: EntityValue + singleton::Sealed {}