css_ast/types/
single_transition.rs

1use super::prelude::*;
2use crate::{EasingFunction, NoneOr, SingleTransitionProperty, Time, TransitionBehaviorValue};
3use css_parse::parse_optionals;
4
5// https://drafts.csswg.org/css-transitions-2/#single-transition
6// <single-transition> = [ none | <single-transition-property> ] || <time> || <easing-function> || <time> || <transition-behavior-value>
7#[derive(ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
9#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
10pub struct SingleTransition<'a> {
11	#[cfg_attr(feature = "visitable", visit(skip))]
12	pub property: Option<NoneOr<SingleTransitionProperty>>,
13	pub duration: Option<Time>,
14	pub easing: Option<EasingFunction<'a>>,
15	pub delay: Option<Time>,
16	#[cfg_attr(feature = "visitable", visit(skip))]
17	pub behavior: Option<TransitionBehaviorValue>,
18}
19
20impl<'a> Peek<'a> for SingleTransition<'a> {
21	fn peek<I>(p: &Parser<'a, I>, c: Cursor) -> bool
22	where
23		I: Iterator<Item = Cursor> + Clone,
24	{
25		<NoneOr<SingleTransitionProperty>>::peek(p, c) || EasingFunction::peek(p, c) || Time::peek(p, c)
26	}
27}
28
29impl<'a> Parse<'a> for SingleTransition<'a> {
30	fn parse<I>(p: &mut Parser<'a, I>) -> ParserResult<Self>
31	where
32		I: Iterator<Item = Cursor> + Clone,
33	{
34		let (easing, property, duration, delay, behavior) = parse_optionals!(p, easing: EasingFunction, property: NoneOr<SingleTransitionProperty>, duration: Time, delay: Time, behavior: TransitionBehaviorValue);
35		Ok(Self { easing, property, duration, delay, behavior })
36	}
37}
38
39#[cfg(test)]
40mod tests {
41	use super::*;
42	use crate::CssAtomSet;
43	use css_parse::{assert_parse, assert_parse_error};
44
45	type NoneOrSingleTransitionProperty = NoneOr<SingleTransitionProperty>;
46
47	#[test]
48	fn size_test() {
49		assert_eq!(std::mem::size_of::<SingleTransition>(), 184);
50	}
51
52	#[test]
53	fn test_writes() {
54		assert_parse!(
55			CssAtomSet::ATOMS,
56			NoneOrSingleTransitionProperty,
57			"none",
58			NoneOrSingleTransitionProperty::None(_)
59		);
60		assert_parse!(
61			CssAtomSet::ATOMS,
62			NoneOrSingleTransitionProperty,
63			"all",
64			NoneOrSingleTransitionProperty::Some(_)
65		);
66
67		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "none");
68		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "opacity");
69		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "opacity 1s");
70		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "opacity 1s ease-in");
71		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "opacity 1s ease-in 2s");
72		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "2s ease-in");
73		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "1s opacity");
74		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "ease-in 1s opacity");
75		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "1s 2s ease-in opacity");
76		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "ease-in opacity 1s 2s");
77		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "ease-in");
78		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "1s");
79		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "1s 2s");
80		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "all 1s ease-in 2s");
81		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "none 1s");
82		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "none 1s normal");
83		assert_parse!(CssAtomSet::ATOMS, SingleTransition, "1s opacity allow-discrete");
84	}
85
86	#[test]
87	fn test_errors() {
88		assert_parse_error!(CssAtomSet::ATOMS, SingleTransition, "1deg");
89		assert_parse_error!(CssAtomSet::ATOMS, SingleTransition, "none none");
90	}
91
92	#[test]
93	#[cfg(feature = "visitable")]
94	fn test_visits() {
95		use crate::assert_visits;
96		assert_visits!("1s", SingleTransition, Time);
97		assert_visits!("ease-in", SingleTransition, EasingFunction);
98		assert_visits!("1s 2s", SingleTransition, Time, Time);
99		assert_visits!("1s ease-in 2s", SingleTransition, Time, EasingFunction, Time);
100	}
101}