use casco::stream::TokenStream;
use super::{Property, PropertyValue};
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum StyleKind {
Image,
Scrollable,
Text,
View,
}
impl StyleKind {
pub fn infer<S>(property: &Property<S>) -> StyleKind
where
S: TokenStream,
{
match &property.value {
PropertyValue::AlignItems(_) => StyleKind::View,
PropertyValue::BackgroundColor(_) => StyleKind::View,
PropertyValue::Border(_) => StyleKind::View,
PropertyValue::BorderRadius(_) => StyleKind::View,
PropertyValue::Bottom(_) => StyleKind::View,
PropertyValue::Color(_) => StyleKind::Text,
PropertyValue::Direction(_) => StyleKind::View,
PropertyValue::FlexBasis(_) => StyleKind::View,
PropertyValue::FlexDirection(_) => StyleKind::View,
PropertyValue::FlexGrow(_) => StyleKind::View,
PropertyValue::FlexShrink(_) => StyleKind::View,
PropertyValue::FontFamily(_) => StyleKind::Text,
PropertyValue::FontSize(_) => StyleKind::Text,
PropertyValue::FontStyle(_) => StyleKind::Text,
PropertyValue::FontWeight(_) => StyleKind::Text,
PropertyValue::Height(_) => StyleKind::View,
PropertyValue::JustifyContent(_) => StyleKind::View,
PropertyValue::Left(_) => StyleKind::View,
PropertyValue::Margin(_) => StyleKind::View,
PropertyValue::MaxHeight(_) => StyleKind::View,
PropertyValue::MaxWidth(_) => StyleKind::View,
PropertyValue::MinHeight(_) => StyleKind::View,
PropertyValue::MinWidth(_) => StyleKind::View,
PropertyValue::ObjectFit(_) => StyleKind::Image,
PropertyValue::Opacity(_) => StyleKind::View,
PropertyValue::Overflow(_) => StyleKind::View,
PropertyValue::Padding(_) => StyleKind::View,
PropertyValue::Position(_) => StyleKind::View,
PropertyValue::Right(_) => StyleKind::View,
PropertyValue::TextAlign(_) => StyleKind::Text,
PropertyValue::TintColor(_) => StyleKind::Image,
PropertyValue::Top(_) => StyleKind::View,
PropertyValue::Transform(_) => StyleKind::View,
PropertyValue::Visibility(_) => StyleKind::View,
PropertyValue::Width(_) => StyleKind::View,
}
}
}
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum StyleCompound {
Image,
ImageView,
Scrollable,
ScrollableView,
Text,
TextView,
View,
Unit,
}
impl StyleCompound {
pub fn infer<I>(kinds: I) -> Option<StyleCompound>
where
I: IntoIterator<Item = StyleKind>,
{
let kinds = kinds.into_iter();
let mut specialization = StyleKind::View;
let mut view = false;
for kind in kinds {
match kind {
StyleKind::View => view = true,
kind if specialization == kind => {}
kind if specialization == StyleKind::View => specialization = kind,
_ => return None,
}
}
Some(match (specialization, view) {
(StyleKind::Image, false) => StyleCompound::Image,
(StyleKind::Image, true) => StyleCompound::ImageView,
(StyleKind::Scrollable, false) => StyleCompound::Scrollable,
(StyleKind::Scrollable, true) => StyleCompound::ScrollableView,
(StyleKind::Text, false) => StyleCompound::Text,
(StyleKind::Text, true) => StyleCompound::TextView,
(StyleKind::View, false) => StyleCompound::Unit,
(StyleKind::View, true) => StyleCompound::View,
})
}
}
#[cfg(test)]
mod tests {
use super::{StyleCompound, StyleKind};
#[test]
fn test_compound() {
assert_eq!(StyleCompound::infer(vec![]), Some(StyleCompound::Unit));
assert_eq!(
StyleCompound::infer(vec![StyleKind::View]),
Some(StyleCompound::View)
);
assert_eq!(
StyleCompound::infer(vec![StyleKind::View, StyleKind::Text]),
Some(StyleCompound::TextView)
);
assert_eq!(
StyleCompound::infer(vec![StyleKind::Image, StyleKind::View, StyleKind::Image]),
Some(StyleCompound::ImageView)
);
}
}