use crate::*; use std::ops::Deref; /// Custom layout and rendering. pub trait Render: Send + Sync { fn layout (&self, area: E::Area) -> E::Area; fn render (&self, output: &mut E); fn boxed <'a> (self) -> RenderBox<'a, E> where Self: Sized + 'a { Box::new(self) as RenderBox<'a, E> } } pub type RenderDyn<'a, Output> = dyn Render + 'a; impl<'a, E: Output> Content for &RenderDyn<'a, E> where Self: Sized { fn content (&self) -> impl Render { self.deref() } fn layout (&self, area: E::Area) -> E::Area { Render::layout(self.deref(), area) } fn render (&self, output: &mut E) { Render::render(self.deref(), output) } } pub type RenderBox<'a, E: Output> = Box>; impl<'a, E: Output> Content for RenderBox<'a, E> { fn content (&self) -> impl Render { self.deref() } //fn boxed <'b> (self) -> RenderBox<'b, E> where Self: Sized + 'b { self } } impl> Render for C { fn layout (&self, area: E::Area) -> E::Area { Content::layout(self, area) } fn render (&self, output: &mut E) { Content::render(self, output) } } #[macro_export] macro_rules! render { (($self:ident:$Struct:ty) => $content:expr) => { impl Content for $Struct { fn content (&$self) -> impl Render { Some($content) } } }; (|$self:ident:$Struct:ident $(< $($L:lifetime),* $($T:ident $(:$Trait:path)?),* >)?, $to:ident | $render:expr) => { impl <$($($L),*)? E: Output, $($T$(:$Trait)?),*> Content for $Struct $(<$($L),* $($T),*>>)? { fn render (&$self, $to: &mut E) { $render } } }; ($Output:ty: ($self:ident:$Struct:ident $(<$( $($L:lifetime)? $($T:ident)? $(:$Trait:path)? ),+>)?) => $content:expr ) => { impl $(<$($($L)? $($T)? $(:$Trait)?),+>)? Content<$Output> for $Struct $(<$($($L)? $($T)?),+>)? { fn content (&$self) -> impl Render<$Output> { $content } } }; ($Output:ty: |$self:ident : $Struct:ident $(<$( $($L:lifetime)? $($T:ident)? $(:$Trait:path)? ),+>)?, $to:ident| $render:expr ) => { impl $(<$($($L)? $($T)? $(:$Trait)?),+>)? Content<$Output> for $Struct $(<$($($L)? $($T)?),+>)? { fn render (&$self, $to: &mut $Output) { $render } } }; }