use alloc::boxed::Box;
use core::any::Any;
use core::any::type_name;
use crate::layout::StretchAxis;
use crate::{AnyView, Environment, View};
#[derive(Debug)]
#[must_use]
pub struct Metadata<T: MetadataKey> {
pub content: AnyView,
pub value: T,
}
pub trait MetadataKey: 'static {}
impl<T: MetadataKey> Metadata<T> {
pub fn new(content: impl View, value: T) -> Self {
Self {
content: AnyView::new(content),
value,
}
}
#[cold]
fn panic_not_caught() {
panic!(
"The metadata `{}` is not caught by your renderer. If the metadata is not essential, use `IgnorableMetadata<T>`.",
type_name::<Self>()
);
}
}
impl<T: MetadataKey> View for Metadata<T> {
fn body(self, _env: &Environment) -> impl View {
Self::panic_not_caught();
}
fn stretch_axis(&self) -> StretchAxis {
self.content.stretch_axis()
}
}
#[derive(Debug)]
pub struct IgnorableMetadata<T: MetadataKey> {
pub content: AnyView,
pub value: T,
}
impl<T: MetadataKey> IgnorableMetadata<T> {
pub fn new(content: impl View, value: T) -> Self {
Self {
content: AnyView::new(content),
value,
}
}
}
impl<T: MetadataKey> View for IgnorableMetadata<T> {
fn body(self, _env: &Environment) -> impl View {
self.content
}
fn stretch_axis(&self) -> StretchAxis {
self.content.stretch_axis()
}
}
#[derive(Debug)]
pub struct Retain {
_value: Box<dyn Any>,
}
impl MetadataKey for Retain {}
impl Retain {
pub fn new<T: 'static>(value: T) -> Self {
Self {
_value: Box::new(value),
}
}
}