ribir_core 0.0.1-alpha.5

Ribir is a framework for building modern native/wasm cross-platform user interface applications.
Documentation
use super::{child_convert::FillVec, *};

/// Trait specify what child a multi child widget can have, and the target type
/// after widget compose its child.
pub trait MultiWithChild<M, C> {
  type Target;
  fn with_child(self, child: C) -> Self::Target;
}

pub struct MultiChildWidget<W> {
  pub widget: W,
  pub children: Vec<Widget>,
}

impl<R, C, M> MultiWithChild<M, C> for R
where
  R: MultiChild,
  C: FillVec<M, Widget>,
{
  type Target = MultiChildWidget<R>;

  fn with_child(self, child: C) -> Self::Target {
    let mut children = vec![];
    child.fill_vec(&mut children);
    MultiChildWidget { widget: self, children }
  }
}

impl<W, C, M> MultiWithChild<M, C> for MultiChildWidget<W>
where
  C: FillVec<M, Widget>,
{
  type Target = Self;
  #[inline]
  fn with_child(mut self, child: C) -> Self::Target {
    child.fill_vec(&mut self.children);
    self
  }
}

impl<R: Render + MultiChild + 'static> IntoWidget<NotSelf<()>> for MultiChildWidget<R> {
  fn into_widget(self) -> Widget {
    let MultiChildWidget { widget, children } = self;
    Widget::Render {
      render: Box::new(widget),
      children: Some(children),
    }
  }
}

#[cfg(test)]
mod tests {
  use super::*;
  use crate::test_helper::MockMulti;

  #[test]
  fn multi_option_child() {
    let _ = MockMulti {}
      .with_child([widget::then(true, || Void)])
      .into_widget();
  }
}