style/values/generics/
size.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! Generic type for CSS properties that are composed by two dimensions.
6
7use crate::parser::ParserContext;
8use crate::Zero;
9use cssparser::Parser;
10use std::fmt::{self, Write};
11use style_traits::{CssWriter, ParseError, ToCss};
12
13/// A generic size, for `border-*-radius` longhand properties, or
14/// `border-spacing`.
15#[derive(
16    Animate,
17    Clone,
18    ComputeSquaredDistance,
19    Copy,
20    Debug,
21    Deserialize,
22    MallocSizeOf,
23    PartialEq,
24    SpecifiedValueInfo,
25    Serialize,
26    ToAnimatedZero,
27    ToAnimatedValue,
28    ToComputedValue,
29    ToResolvedValue,
30    ToShmem,
31)]
32#[allow(missing_docs)]
33#[repr(C)]
34pub struct Size2D<L> {
35    pub width: L,
36    pub height: L,
37}
38
39impl<L> Size2D<L> {
40    #[inline]
41    /// Create a new `Size2D` for an area of given width and height.
42    pub fn new(width: L, height: L) -> Self {
43        Self { width, height }
44    }
45
46    /// Returns the width component.
47    pub fn width(&self) -> &L {
48        &self.width
49    }
50
51    /// Returns the height component.
52    pub fn height(&self) -> &L {
53        &self.height
54    }
55
56    /// Parse a `Size2D` with a given parsing function.
57    pub fn parse_with<'i, 't, F>(
58        context: &ParserContext,
59        input: &mut Parser<'i, 't>,
60        parse_one: F,
61    ) -> Result<Self, ParseError<'i>>
62    where
63        L: Clone,
64        F: Fn(&ParserContext, &mut Parser<'i, 't>) -> Result<L, ParseError<'i>>,
65    {
66        let first = parse_one(context, input)?;
67        let second = input
68            .try_parse(|i| parse_one(context, i))
69            .unwrap_or_else(|_| first.clone());
70        Ok(Self::new(first, second))
71    }
72}
73
74impl<L> ToCss for Size2D<L>
75where
76    L: ToCss + PartialEq,
77{
78    fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
79    where
80        W: Write,
81    {
82        self.width.to_css(dest)?;
83
84        if self.height != self.width {
85            dest.write_char(' ')?;
86            self.height.to_css(dest)?;
87        }
88
89        Ok(())
90    }
91}
92
93impl<L: Zero> Zero for Size2D<L> {
94    fn zero() -> Self {
95        Self::new(L::zero(), L::zero())
96    }
97
98    fn is_zero(&self) -> bool {
99        self.width.is_zero() && self.height.is_zero()
100    }
101}