css_ast/types/
ratio.rs

1use crate::units::CSSInt;
2use css_parse::{Parse, Parser, Result as ParserResult, T};
3use csskit_derives::{Peek, ToCursors, ToSpan, Visitable};
4
5// https://drafts.csswg.org/css-values-4/#ratios
6#[derive(Peek, ToCursors, ToSpan, Visitable, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
8#[visit(self)]
9pub struct Ratio {
10	pub numerator: CSSInt,
11	pub slash: Option<T![/]>,
12	pub denominator: Option<CSSInt>,
13}
14
15impl<'a> Parse<'a> for Ratio {
16	fn parse(p: &mut Parser<'a>) -> ParserResult<Self> {
17		let numerator = p.parse::<CSSInt>()?;
18		let slash = p.parse_if_peek::<T![/]>()?;
19		let denominator = if slash.is_some() { Some(p.parse::<CSSInt>()?) } else { None };
20		Ok(Self { numerator, slash, denominator })
21	}
22}
23
24#[cfg(test)]
25mod tests {
26	use super::*;
27	use css_parse::{assert_parse, assert_parse_error};
28
29	#[test]
30	fn size_test() {
31		assert_eq!(std::mem::size_of::<Ratio>(), 44);
32	}
33
34	#[test]
35	fn test_writes() {
36		assert_parse!(Ratio, "1/1");
37		assert_parse!(Ratio, "5/3");
38		assert_parse!(Ratio, "5");
39	}
40
41	#[test]
42	fn test_errors() {
43		assert_parse_error!(Ratio, "5 : 3");
44		assert_parse_error!(Ratio, "5 / 1 / 1");
45	}
46
47	// #[cfg(feature = "serde")]
48	// #[test]
49	// fn test_serializes() {
50	// 	assert_json!(Ratio, "5/3", {
51	// 		"node": [5, 3],
52	// 		"start": 0,
53	// 		"end": 5
54	// 	});
55	// }
56}