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