use std::rc::Rc;
use std::sync::Arc;
use std::borrow::BorrowMut;
use futures_signals::signal::{Signal};
use futures_signals::signal_vec::SignalVec;
use web_sys::Node;
use crate::dom::{Dom, DomBuilder};
use crate::traits::*;
#[cfg(doc)]
use crate::{fragment, box_fragment};
pub trait Fragment {
fn apply<'a>(&self, dom: FragmentBuilder<'a>) -> FragmentBuilder<'a>;
}
impl<A> Fragment for &A where A: Fragment + ?Sized {
#[inline]
fn apply<'a>(&self, dom: FragmentBuilder<'a>) -> FragmentBuilder<'a> {
(*self).apply(dom)
}
}
impl<A> Fragment for Box<A> where A: Fragment + ?Sized {
#[inline]
fn apply<'a>(&self, dom: FragmentBuilder<'a>) -> FragmentBuilder<'a> {
(**self).apply(dom)
}
}
impl<A> Fragment for Rc<A> where A: Fragment + ?Sized {
#[inline]
fn apply<'a>(&self, dom: FragmentBuilder<'a>) -> FragmentBuilder<'a> {
(**self).apply(dom)
}
}
impl<A> Fragment for Arc<A> where A: Fragment + ?Sized {
#[inline]
fn apply<'a>(&self, dom: FragmentBuilder<'a>) -> FragmentBuilder<'a> {
(**self).apply(dom)
}
}
pub type BoxFragment = Box<dyn Fragment + Send + Sync>;
#[must_use]
#[derive(Debug)]
pub struct FragmentBuilder<'a>(pub(crate) DomBuilder<&'a Node>);
impl<'a> FragmentBuilder<'a> {
#[inline]
pub fn apply<F>(self, f: F) -> Self where F: FnOnce(Self) -> Self {
f(self)
}
#[inline]
pub fn apply_if<F>(self, test: bool, f: F) -> Self where F: FnOnce(Self) -> Self {
if test {
f(self)
} else {
self
}
}
#[inline]
#[track_caller]
pub fn fragment<F>(self, fragment: &F) -> Self where F: Fragment {
fragment.apply(self)
}
#[inline]
#[track_caller]
pub fn text(self, value: &str) -> Self {
Self(self.0.text(value))
}
#[inline]
#[track_caller]
pub fn text_signal<B, C>(self, value: C) -> Self
where B: AsStr,
C: Signal<Item = B> + 'static {
Self(self.0.text_signal(value))
}
#[inline]
#[track_caller]
pub fn child<B: BorrowMut<Dom>>(self, child: B) -> Self {
Self(self.0.child(child))
}
#[inline]
#[track_caller]
pub fn child_signal<B>(self, child: B) -> Self
where B: Signal<Item = Option<Dom>> + 'static {
Self(self.0.child_signal(child))
}
#[inline]
#[track_caller]
pub fn children<B: BorrowMut<Dom>, C: IntoIterator<Item = B>>(self, children: C) -> Self {
Self(self.0.children(children))
}
#[inline]
#[track_caller]
pub fn children_signal_vec<B>(self, children: B) -> Self
where B: SignalVec<Item = Dom> + 'static {
Self(self.0.children_signal_vec(children))
}
}
#[macro_export]
macro_rules! fragment {
() => {
$crate::__internal::fragment(|dom| dom)
};
(move { $($input:tt)* }) => {
$crate::__internal::fragment(move |dom| $crate::apply_methods!(dom, { $($input)* }))
};
({ $($input:tt)* }) => {
$crate::__internal::fragment(|dom| $crate::apply_methods!(dom, { $($input)* }))
};
}
#[macro_export]
macro_rules! box_fragment {
() => {
$crate::__internal::box_fragment(|dom| dom)
};
(move { $($input:tt)* }) => {
$crate::__internal::box_fragment(move |dom| $crate::apply_methods!(dom, { $($input)* }))
};
({ $($input:tt)* }) => {
$crate::__internal::box_fragment(|dom| $crate::apply_methods!(dom, { $($input)* }))
};
}