mod private {
pub trait Sealed {}
impl Sealed for () {}
impl<T, L: Sealed + super::IsRenderList> Sealed for super::RenderTList<T, L> {}
}
pub trait IsRenderList: private::Sealed {}
impl IsRenderList for () {}
impl<T, L: IsRenderList> IsRenderList for RenderTList<T, L> {}
#[derive(Clone, Debug)]
#[cfg_attr(
feature = "serialization",
derive(serde::Serialize, serde::Deserialize)
)]
#[cfg_attr(
feature = "serialization",
serde(bound(deserialize = "
T: serde::de::DeserializeOwned,
L: serde::de::DeserializeOwned,
"))
)]
pub enum RenderTList<T, L: IsRenderList> {
Type(T),
List(L),
}
pub struct Here;
pub struct There<Idx>(std::marker::PhantomData<Idx>);
pub trait Embed<Target, Idx> {
fn embed(self) -> Target;
}
impl<T, L: IsRenderList> Embed<RenderTList<T, L>, Here> for RenderTList<T, L> {
fn embed(self) -> RenderTList<T, L> {
self
}
}
impl<H, TailTarget, Source, Idx> Embed<RenderTList<H, TailTarget>, There<Idx>> for Source
where
TailTarget: IsRenderList,
Source: Embed<TailTarget, Idx>,
{
fn embed(self) -> RenderTList<H, TailTarget> {
RenderTList::List(self.embed())
}
}
#[cfg(test)]
mod test {
use crate::render_commands::render_t_list::{Embed, Here, RenderTList, There};
type Full = RenderTList<i32, RenderTList<i32, ()>>;
#[test]
fn embeds_sublist_at_tail_position() {
let sub = RenderTList::Type(42);
let full = Embed::<Full, There<Here>>::embed(sub);
match full {
RenderTList::List(RenderTList::Type(42)) => {}
other => panic!("unexpected embed result: {other:?}"),
}
}
}