use async_trait::async_trait; use crate::{AsyncWidget, Frame, Size, Widget, WidthDb}; pub struct Boxed<'a, E>(Box + 'a>); impl<'a, E> Boxed<'a, E> { pub fn new(inner: I) -> Self where I: Widget + 'a, { Self(Box::new(inner)) } } trait WidgetWrapper { fn wrap_size( &self, widthdb: &mut WidthDb, max_width: Option, max_height: Option, ) -> Result; fn wrap_draw(self: Box, frame: &mut Frame) -> Result<(), E>; } impl WidgetWrapper for W where W: Widget, { fn wrap_size( &self, widthdb: &mut WidthDb, max_width: Option, max_height: Option, ) -> Result { self.size(widthdb, max_width, max_height) } fn wrap_draw(self: Box, frame: &mut Frame) -> Result<(), E> { (*self).draw(frame) } } impl Widget for Boxed<'_, E> { fn size( &self, widthdb: &mut WidthDb, max_width: Option, max_height: Option, ) -> Result { self.0.wrap_size(widthdb, max_width, max_height) } fn draw(self, frame: &mut Frame) -> Result<(), E> { self.0.wrap_draw(frame) } } pub struct BoxedAsync<'a, E>(Box + Send + Sync + 'a>); impl<'a, E> BoxedAsync<'a, E> { pub fn new(inner: I) -> Self where I: AsyncWidget + Send + Sync + 'a, { Self(Box::new(inner)) } } #[async_trait] trait AsyncWidgetWrapper { async fn wrap_size( &self, widthdb: &mut WidthDb, max_width: Option, max_height: Option, ) -> Result; async fn wrap_draw(self: Box, frame: &mut Frame) -> Result<(), E>; } #[async_trait] impl AsyncWidgetWrapper for W where W: AsyncWidget + Send + Sync, { async fn wrap_size( &self, widthdb: &mut WidthDb, max_width: Option, max_height: Option, ) -> Result { self.size(widthdb, max_width, max_height).await } async fn wrap_draw(self: Box, frame: &mut Frame) -> Result<(), E> { (*self).draw(frame).await } } #[async_trait] impl AsyncWidget for BoxedAsync<'_, E> { async fn size( &self, widthdb: &mut WidthDb, max_width: Option, max_height: Option, ) -> Result { self.0.wrap_size(widthdb, max_width, max_height).await } async fn draw(self, frame: &mut Frame) -> Result<(), E> { self.0.wrap_draw(frame).await } }