use std::marker::PhantomData;
use kdl::KdlNode;
use palkia::prelude::*;
use serde::de::DeserializeOwned;
pub trait ComponentFactory<Ctx>: Send + Sync + 'static
where
Ctx: 'static,
{
fn assemble<'a, 'w>(
&self,
builder: EntityBuilder<'a, 'w>,
node: &KdlNode,
ctx: &Ctx,
) -> eyre::Result<EntityBuilder<'a, 'w>>;
}
pub struct SerdeComponentFactory<T, Ctx>(PhantomData<fn(&Ctx) -> T>);
impl<T, Ctx> SerdeComponentFactory<T, Ctx> {
pub fn new() -> Self {
Self(PhantomData)
}
}
impl<T, Ctx> ComponentFactory<Ctx> for SerdeComponentFactory<T, Ctx>
where
Self: 'static,
T: DeserializeOwned + Component,
{
fn assemble<'a, 'w>(
&self,
mut builder: EntityBuilder<'a, 'w>,
node: &KdlNode,
_ctx: &Ctx,
) -> eyre::Result<EntityBuilder<'a, 'w>> {
let comp: T = knurdy::deserialize_node(node)?;
builder.insert(comp);
Ok(builder)
}
}