use serde::{Deserialize, Serialize}; use specs::{SystemData, Component, DerefFlaggedStorage}; use specs_idvs::IdvStorage; use std::{ ops::Deref, sync::Arc, }; pub trait Link: Sized + Send + Sync + 'static { type CreateData<'a>: SystemData<'a>; fn create(this: &LinkHandle, data: Self::CreateData<'_>) -> Result<(), ()>; 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: self.link.clone() } } } 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 } }