parcel_css/values/
ratio.rs

1//! CSS ratio values.
2
3use super::number::CSSNumber;
4use crate::error::{ParserError, PrinterError};
5use crate::printer::Printer;
6use crate::traits::{Parse, ToCss};
7use cssparser::*;
8
9/// A CSS [`<ratio>`](https://www.w3.org/TR/css-values-4/#ratios) value,
10/// representing the ratio of two numeric values.
11#[derive(Debug, Clone, PartialEq)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct Ratio(pub CSSNumber, pub CSSNumber);
14
15impl<'i> Parse<'i> for Ratio {
16  fn parse<'t>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i, ParserError<'i>>> {
17    let first = CSSNumber::parse(input)?;
18    let second = if input.try_parse(|input| input.expect_delim('/')).is_ok() {
19      CSSNumber::parse(input)?
20    } else {
21      1.0
22    };
23
24    Ok(Ratio(first, second))
25  }
26}
27
28impl Ratio {
29  /// Parses a ratio where both operands are required.
30  pub fn parse_required<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i, ParserError<'i>>> {
31    let first = CSSNumber::parse(input)?;
32    input.expect_delim('/')?;
33    let second = CSSNumber::parse(input)?;
34    Ok(Ratio(first, second))
35  }
36}
37
38impl ToCss for Ratio {
39  fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
40  where
41    W: std::fmt::Write,
42  {
43    self.0.to_css(dest)?;
44    if self.1 != 1.0 {
45      dest.delim('/', true)?;
46      self.1.to_css(dest)?;
47    }
48    Ok(())
49  }
50}
51
52impl std::ops::Add<CSSNumber> for Ratio {
53  type Output = Self;
54
55  fn add(self, other: CSSNumber) -> Ratio {
56    Ratio(self.0 + other, self.1)
57  }
58}