use serde::{Deserialize, Serialize}; use specs::{Component, DerefFlaggedStorage, SystemData}; use specs_idvs::IdvStorage; use std::{ops::Deref, sync::Arc}; pub trait Link: Sized + Send + Sync + 'static { type Error; type CreateData<'a>: SystemData<'a>; fn create(this: &LinkHandle, data: Self::CreateData<'_>) -> Result<(), Self::Error>; type PersistData<'a>: SystemData<'a>; fn persist(this: &LinkHandle, data: Self::PersistData<'_>) -> bool; type DeleteData<'a>: SystemData<'a>; fn delete(this: &LinkHandle, data: Self::DeleteData<'_>); } pub trait Role { type Link: Link; } #[derive(Serialize, Deserialize, Debug)] pub struct Is { #[serde(bound(serialize = "R::Link: Serialize"))] #[serde(bound(deserialize = "R::Link: Deserialize<'de>"))] link: LinkHandle, } impl Is { pub fn delete(&self, data: ::DeleteData<'_>) { R::Link::delete(&self.link, data) } } impl Clone for Is { fn clone(&self) -> Self { Self { link: self.link.clone(), } } } impl Deref for Is { type Target = R::Link; fn deref(&self) -> &Self::Target { &self.link } } impl Component for Is where R::Link: Send + Sync + 'static, { type Storage = DerefFlaggedStorage>; } #[derive(Serialize, Deserialize, Debug)] pub struct LinkHandle { link: Arc, } impl Clone for LinkHandle { fn clone(&self) -> Self { Self { link: Arc::clone(&self.link), } } } impl LinkHandle { pub fn from_link(link: L) -> Self { Self { link: Arc::new(link), } } pub fn make_role>(&self) -> Is { Is { link: self.clone() } } } impl Deref for LinkHandle { type Target = L; fn deref(&self) -> &Self::Target { &self.link } }