use kempt::Map;
use crate::any::AnyComponent;
use crate::components::DynamicComponent;
use crate::names::NameKey;
use crate::{Name, StyleComponent};
#[derive(Default, Clone)]
pub struct Style {
components: Map<NameKey<'static>, AnyComponent>,
}
impl std::fmt::Debug for Style {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut t = f.debug_tuple("Style");
for component in self.components.values() {
t.field(component);
}
t.finish()
}
}
impl Style {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
components: Map::with_capacity(capacity),
}
}
pub fn push<T: DynamicComponent + Clone>(&mut self, component: T) {
let c = AnyComponent::new(component);
self.components.insert(NameKey::from(c.name()), c);
}
#[must_use]
pub fn with<T: DynamicComponent + Clone>(mut self, component: T) -> Self {
self.push(component);
self
}
#[must_use]
pub fn get<T: StyleComponent>(&self) -> Option<&T> {
self.components
.get(&NameKey::from(T::name()))
.and_then(AnyComponent::get)
}
#[must_use]
pub fn get_by_name(&self, name: &Name) -> Option<&AnyComponent> {
self.components.get(&NameKey::from(name))
}
#[must_use]
pub fn get_or_default<T: StyleComponent + Default + Clone>(&self) -> T {
self.get::<T>().cloned().unwrap_or_default()
}
#[must_use]
pub fn merged_with(mut self, other: &Self) -> Self {
self.components.merge_with(
&other.components,
|_key, value| Some(value.clone()),
|_key, mine, other| mine.merge_with(other),
);
self
}
#[must_use]
pub fn inherited_from(mut self, parent: &Self) -> Self {
self.components.merge_with(
&parent.components,
|_key, value| value.inherited().then(|| value.clone()),
|_key, mine, other| {
if other.inherited() {
mine.merge_with(other);
}
},
);
self
}
#[must_use]
pub fn len(&self) -> usize {
self.components.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.components.is_empty()
}
#[must_use]
pub fn iter(&self) -> Iter<'_> {
self.into_iter()
}
}
impl<'a> IntoIterator for &'a Style {
type IntoIter = Iter<'a>;
type Item = &'a AnyComponent;
fn into_iter(self) -> Self::IntoIter {
Iter(self.components.values())
}
}
impl IntoIterator for Style {
type IntoIter = IntoIter;
type Item = AnyComponent;
fn into_iter(self) -> Self::IntoIter {
IntoIter(self.components.into_values())
}
}
pub struct Iter<'a>(kempt::map::Values<'a, NameKey<'static>, AnyComponent>);
impl<'a> Iterator for Iter<'a> {
type Item = &'a AnyComponent;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}
pub struct IntoIter(kempt::map::IntoValues<NameKey<'static>, AnyComponent>);
impl Iterator for IntoIter {
type Item = AnyComponent;
fn next(&mut self) -> Option<Self::Item> {
self.0.next()
}
}