use crate::{corety::AzString, props::formatter::PrintAsCssValue};
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C)]
pub enum StyleSpatialNavigationAction {
#[default]
Auto,
Focus,
Scroll,
}
impl PrintAsCssValue for StyleSpatialNavigationAction {
fn print_as_css_value(&self) -> String {
String::from(match self {
Self::Auto => "auto",
Self::Focus => "focus",
Self::Scroll => "scroll",
})
}
}
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C)]
pub enum StyleSpatialNavigationContain {
#[default]
Auto,
Contain,
}
impl PrintAsCssValue for StyleSpatialNavigationContain {
fn print_as_css_value(&self) -> String {
String::from(match self {
Self::Auto => "auto",
Self::Contain => "contain",
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum CssSpatialNavigationActionParseError<'a> {
InvalidValue(&'a str),
}
impl core::fmt::Display for CssSpatialNavigationActionParseError<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::InvalidValue(v) => write!(
f,
"Invalid spatial-navigation-action value: \"{v}\" (expected auto, focus or scroll)"
),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C, u8)]
pub enum CssSpatialNavigationActionParseErrorOwned {
InvalidValue(AzString),
}
impl<'a> CssSpatialNavigationActionParseError<'a> {
#[must_use]
pub fn to_contained(&self) -> CssSpatialNavigationActionParseErrorOwned {
match self {
Self::InvalidValue(v) => {
CssSpatialNavigationActionParseErrorOwned::InvalidValue((*v).into())
}
}
}
}
impl CssSpatialNavigationActionParseErrorOwned {
#[must_use]
pub fn to_shared(&self) -> CssSpatialNavigationActionParseError<'_> {
match self {
Self::InvalidValue(v) => CssSpatialNavigationActionParseError::InvalidValue(v.as_str()),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum CssSpatialNavigationContainParseError<'a> {
InvalidValue(&'a str),
}
impl core::fmt::Display for CssSpatialNavigationContainParseError<'_> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::InvalidValue(v) => write!(
f,
"Invalid spatial-navigation-contain value: \"{v}\" (expected auto or contain)"
),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C, u8)]
pub enum CssSpatialNavigationContainParseErrorOwned {
InvalidValue(AzString),
}
impl<'a> CssSpatialNavigationContainParseError<'a> {
#[must_use]
pub fn to_contained(&self) -> CssSpatialNavigationContainParseErrorOwned {
match self {
Self::InvalidValue(v) => {
CssSpatialNavigationContainParseErrorOwned::InvalidValue((*v).into())
}
}
}
}
impl CssSpatialNavigationContainParseErrorOwned {
#[must_use]
pub fn to_shared(&self) -> CssSpatialNavigationContainParseError<'_> {
match self {
Self::InvalidValue(v) => {
CssSpatialNavigationContainParseError::InvalidValue(v.as_str())
}
}
}
}
#[cfg(feature = "parser")]
pub fn parse_style_spatial_navigation_action(
input: &str,
) -> Result<StyleSpatialNavigationAction, CssSpatialNavigationActionParseError<'_>> {
match input.trim() {
"auto" => Ok(StyleSpatialNavigationAction::Auto),
"focus" => Ok(StyleSpatialNavigationAction::Focus),
"scroll" => Ok(StyleSpatialNavigationAction::Scroll),
_ => Err(CssSpatialNavigationActionParseError::InvalidValue(input)),
}
}
#[cfg(feature = "parser")]
pub fn parse_style_spatial_navigation_contain(
input: &str,
) -> Result<StyleSpatialNavigationContain, CssSpatialNavigationContainParseError<'_>> {
match input.trim() {
"auto" => Ok(StyleSpatialNavigationContain::Auto),
"contain" => Ok(StyleSpatialNavigationContain::Contain),
_ => Err(CssSpatialNavigationContainParseError::InvalidValue(input)),
}
}
#[cfg(all(test, feature = "parser"))]
mod tests {
use super::*;
#[test]
fn the_action_keywords_parse_and_round_trip() {
for (text, value) in [
("auto", StyleSpatialNavigationAction::Auto),
("focus", StyleSpatialNavigationAction::Focus),
("scroll", StyleSpatialNavigationAction::Scroll),
] {
assert_eq!(parse_style_spatial_navigation_action(text), Ok(value));
assert_eq!(value.print_as_css_value(), text);
}
assert_eq!(
parse_style_spatial_navigation_action(" scroll "),
Ok(StyleSpatialNavigationAction::Scroll)
);
}
#[test]
fn the_contain_keywords_parse_and_round_trip() {
for (text, value) in [
("auto", StyleSpatialNavigationContain::Auto),
("contain", StyleSpatialNavigationContain::Contain),
] {
assert_eq!(parse_style_spatial_navigation_contain(text), Ok(value));
assert_eq!(value.print_as_css_value(), text);
}
}
#[test]
fn a_wrong_keyword_is_an_error_and_not_the_default() {
assert!(parse_style_spatial_navigation_action("none").is_err());
assert!(parse_style_spatial_navigation_action("contain").is_err());
assert!(parse_style_spatial_navigation_contain("none").is_err());
assert!(parse_style_spatial_navigation_contain("focus").is_err());
}
#[test]
fn both_properties_parse_from_their_css_name() {
use crate::props::property::{
get_css_key_map, parse_css_property, CssProperty, CssPropertyType,
};
let map = get_css_key_map();
let ty = CssPropertyType::from_str("spatial-navigation-action", &map)
.expect("`spatial-navigation-action` must be a known property name");
assert_eq!(ty, CssPropertyType::SpatialNavigationAction);
assert_eq!(
parse_css_property(ty, "scroll"),
Ok(CssProperty::SpatialNavigationAction(
crate::css::CssPropertyValue::Exact(StyleSpatialNavigationAction::Scroll)
))
);
let ty = CssPropertyType::from_str("spatial-navigation-contain", &map)
.expect("`spatial-navigation-contain` must be a known property name");
assert_eq!(ty, CssPropertyType::SpatialNavigationContain);
assert_eq!(
parse_css_property(ty, "contain"),
Ok(CssProperty::SpatialNavigationContain(
crate::css::CssPropertyValue::Exact(StyleSpatialNavigationContain::Contain)
))
);
assert!(!CssPropertyType::SpatialNavigationAction.can_trigger_relayout());
assert!(!CssPropertyType::SpatialNavigationContain.can_trigger_relayout());
}
#[test]
fn both_properties_default_to_auto() {
assert_eq!(
StyleSpatialNavigationAction::default(),
StyleSpatialNavigationAction::Auto
);
assert_eq!(
StyleSpatialNavigationContain::default(),
StyleSpatialNavigationContain::Auto
);
}
}