use crate::into_view::{IntoView, View};
use std::{
fmt::{self, Debug},
sync::Arc,
};
use tachys::view::{
any_view::{AnyView, IntoAny},
fragment::{Fragment, IntoFragment},
RenderHtml,
};
pub type Children = Box<dyn FnOnce() -> AnyView + Send>;
pub type ChildrenFragment = Box<dyn FnOnce() -> Fragment + Send>;
pub type ChildrenFn = Arc<dyn Fn() -> AnyView + Send + Sync>;
pub type ChildrenFragmentFn = Arc<dyn Fn() -> Fragment + Send>;
pub type ChildrenFnMut = Box<dyn FnMut() -> AnyView + Send>;
pub type ChildrenFragmentMut = Box<dyn FnMut() -> Fragment + Send>;
type BoxedChildrenFn = Box<dyn Fn() -> AnyView + Send>;
pub trait ToChildren<F> {
fn to_children(f: F) -> Self;
}
pub struct ChildrenOptContainer<T>(pub T);
impl<F, C> ToChildren<F> for Children
where
F: FnOnce() -> C + Send + 'static,
C: RenderHtml + Send + 'static,
{
#[inline]
fn to_children(f: F) -> Self {
Box::new(move || f().into_any())
}
}
impl<T> ToChildren<ChildrenOptContainer<T>> for Children
where
T: IntoAny + Send + 'static,
{
#[inline]
fn to_children(t: ChildrenOptContainer<T>) -> Self {
Box::new(move || t.0.into_any())
}
}
impl<F, C> ToChildren<F> for ChildrenFn
where
F: Fn() -> C + Send + Sync + 'static,
C: RenderHtml + Send + 'static,
{
#[inline]
fn to_children(f: F) -> Self {
Arc::new(move || f().into_any())
}
}
impl<T> ToChildren<ChildrenOptContainer<T>> for ChildrenFn
where
T: IntoAny + Clone + Send + Sync + 'static,
{
#[inline]
fn to_children(t: ChildrenOptContainer<T>) -> Self {
Arc::new(move || t.0.clone().into_any())
}
}
impl<F, C> ToChildren<F> for ChildrenFnMut
where
F: Fn() -> C + Send + 'static,
C: RenderHtml + Send + 'static,
{
#[inline]
fn to_children(f: F) -> Self {
Box::new(move || f().into_any())
}
}
impl<T> ToChildren<ChildrenOptContainer<T>> for ChildrenFnMut
where
T: IntoAny + Clone + Send + 'static,
{
#[inline]
fn to_children(t: ChildrenOptContainer<T>) -> Self {
Box::new(move || t.0.clone().into_any())
}
}
impl<F, C> ToChildren<F> for BoxedChildrenFn
where
F: Fn() -> C + Send + 'static,
C: RenderHtml + Send + 'static,
{
#[inline]
fn to_children(f: F) -> Self {
Box::new(move || f().into_any())
}
}
impl<T> ToChildren<ChildrenOptContainer<T>> for BoxedChildrenFn
where
T: IntoAny + Clone + Send + 'static,
{
#[inline]
fn to_children(t: ChildrenOptContainer<T>) -> Self {
Box::new(move || t.0.clone().into_any())
}
}
impl<F, C> ToChildren<F> for ChildrenFragment
where
F: FnOnce() -> C + Send + 'static,
C: IntoFragment,
{
#[inline]
fn to_children(f: F) -> Self {
Box::new(move || f().into_fragment())
}
}
impl<T> ToChildren<ChildrenOptContainer<T>> for ChildrenFragment
where
T: IntoAny + Send + 'static,
{
#[inline]
fn to_children(t: ChildrenOptContainer<T>) -> Self {
Box::new(move || Fragment::new(vec![t.0.into_any()]))
}
}
impl<F, C> ToChildren<F> for ChildrenFragmentFn
where
F: Fn() -> C + Send + 'static,
C: IntoFragment,
{
#[inline]
fn to_children(f: F) -> Self {
Arc::new(move || f().into_fragment())
}
}
impl<T> ToChildren<ChildrenOptContainer<T>> for ChildrenFragmentFn
where
T: IntoAny + Clone + Send + 'static,
{
#[inline]
fn to_children(t: ChildrenOptContainer<T>) -> Self {
Arc::new(move || Fragment::new(vec![t.0.clone().into_any()]))
}
}
impl<F, C> ToChildren<F> for ChildrenFragmentMut
where
F: FnMut() -> C + Send + 'static,
C: IntoFragment,
{
#[inline]
fn to_children(mut f: F) -> Self {
Box::new(move || f().into_fragment())
}
}
impl<T> ToChildren<ChildrenOptContainer<T>> for ChildrenFragmentMut
where
T: IntoAny + Clone + Send + 'static,
{
#[inline]
fn to_children(t: ChildrenOptContainer<T>) -> Self {
Box::new(move || Fragment::new(vec![t.0.clone().into_any()]))
}
}
#[derive(Clone)]
pub struct ViewFn(Arc<dyn Fn() -> AnyView + Send + Sync + 'static>);
impl Default for ViewFn {
fn default() -> Self {
Self(Arc::new(|| ().into_any()))
}
}
impl<F, C> From<F> for ViewFn
where
F: Fn() -> C + Send + Sync + 'static,
C: RenderHtml + Send + 'static,
{
fn from(value: F) -> Self {
Self(Arc::new(move || value().into_any()))
}
}
impl<C> From<View<C>> for ViewFn
where
C: Clone + Send + Sync + 'static,
View<C>: IntoAny,
{
fn from(value: View<C>) -> Self {
Self(Arc::new(move || value.clone().into_any()))
}
}
impl ViewFn {
pub fn run(&self) -> AnyView {
(self.0)()
}
}
pub struct ViewFnOnce(Box<dyn FnOnce() -> AnyView + Send + 'static>);
impl Default for ViewFnOnce {
fn default() -> Self {
Self(Box::new(|| ().into_any()))
}
}
impl<F, C> From<F> for ViewFnOnce
where
F: FnOnce() -> C + Send + 'static,
C: RenderHtml + Send + 'static,
{
fn from(value: F) -> Self {
Self(Box::new(move || value().into_any()))
}
}
impl<C> From<View<C>> for ViewFnOnce
where
C: Send + Sync + 'static,
View<C>: IntoAny,
{
fn from(value: View<C>) -> Self {
Self(Box::new(move || value.into_any()))
}
}
impl ViewFnOnce {
pub fn run(self) -> AnyView {
(self.0)()
}
}
pub struct TypedChildren<T>(Box<dyn FnOnce() -> View<T> + Send>);
impl<T> TypedChildren<T> {
pub fn into_inner(self) -> impl FnOnce() -> View<T> + Send {
self.0
}
}
impl<F, C> ToChildren<F> for TypedChildren<C>
where
F: FnOnce() -> C + Send + 'static,
C: IntoView,
C::AsyncOutput: Send,
{
#[inline]
fn to_children(f: F) -> Self {
TypedChildren(Box::new(move || f().into_view()))
}
}
impl<T> ToChildren<ChildrenOptContainer<T>> for TypedChildren<T>
where
T: IntoView + 'static,
{
#[inline]
fn to_children(t: ChildrenOptContainer<T>) -> Self {
TypedChildren(Box::new(move || t.0.into_view()))
}
}
pub struct TypedChildrenMut<T>(Box<dyn FnMut() -> View<T> + Send>);
impl<T> Debug for TypedChildrenMut<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("TypedChildrenMut").finish()
}
}
impl<T> TypedChildrenMut<T> {
pub fn into_inner(self) -> impl FnMut() -> View<T> + Send {
self.0
}
}
impl<F, C> ToChildren<F> for TypedChildrenMut<C>
where
F: FnMut() -> C + Send + 'static,
C: IntoView,
C::AsyncOutput: Send,
{
#[inline]
fn to_children(mut f: F) -> Self {
TypedChildrenMut(Box::new(move || f().into_view()))
}
}
impl<T> ToChildren<ChildrenOptContainer<T>> for TypedChildrenMut<T>
where
T: IntoView + Clone + 'static,
{
#[inline]
fn to_children(t: ChildrenOptContainer<T>) -> Self {
TypedChildrenMut(Box::new(move || t.0.clone().into_view()))
}
}
pub struct TypedChildrenFn<T>(Arc<dyn Fn() -> View<T> + Send + Sync>);
impl<T> Debug for TypedChildrenFn<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("TypedChildrenFn").finish()
}
}
impl<T> Clone for TypedChildrenFn<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T> TypedChildrenFn<T> {
pub fn into_inner(self) -> Arc<dyn Fn() -> View<T> + Send + Sync> {
self.0
}
}
impl<F, C> ToChildren<F> for TypedChildrenFn<C>
where
F: Fn() -> C + Send + Sync + 'static,
C: IntoView,
C::AsyncOutput: Send,
{
#[inline]
fn to_children(f: F) -> Self {
TypedChildrenFn(Arc::new(move || f().into_view()))
}
}
impl<T> ToChildren<ChildrenOptContainer<T>> for TypedChildrenFn<T>
where
T: IntoView + Clone + Sync + 'static,
{
#[inline]
fn to_children(t: ChildrenOptContainer<T>) -> Self {
TypedChildrenFn(Arc::new(move || t.0.clone().into_view()))
}
}