lightningcss/values/
rect.rs1use crate::error::{ParserError, PrinterError};
4use crate::printer::Printer;
5use crate::traits::{IsCompatible, Parse, ToCss};
6#[cfg(feature = "visitor")]
7use crate::visitor::Visit;
8use cssparser::*;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
16#[cfg_attr(feature = "visitor", derive(Visit))]
17#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
18#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
19#[cfg_attr(feature = "into_owned", derive(static_self::IntoOwned))]
20pub struct Rect<T>(
21 pub T,
23 pub T,
25 pub T,
27 pub T,
29);
30
31impl<T> Rect<T> {
32 pub fn new(first: T, second: T, third: T, fourth: T) -> Self {
34 Rect(first, second, third, fourth)
35 }
36}
37
38impl<T: Default + Clone> Default for Rect<T> {
39 fn default() -> Rect<T> {
40 Rect::all(T::default())
41 }
42}
43
44impl<T> Rect<T>
45where
46 T: Clone,
47{
48 pub fn all(v: T) -> Self {
50 Rect::new(v.clone(), v.clone(), v.clone(), v)
51 }
52
53 pub fn parse_with<'i, 't, Parse>(
55 input: &mut Parser<'i, 't>,
56 parse: Parse,
57 ) -> Result<Self, ParseError<'i, ParserError<'i>>>
58 where
59 Parse: Fn(&mut Parser<'i, 't>) -> Result<T, ParseError<'i, ParserError<'i>>>,
60 {
61 let first = parse(input)?;
62 let second = if let Ok(second) = input.try_parse(|i| parse(i)) {
63 second
64 } else {
65 return Ok(Self::new(first.clone(), first.clone(), first.clone(), first));
67 };
68 let third = if let Ok(third) = input.try_parse(|i| parse(i)) {
69 third
70 } else {
71 return Ok(Self::new(first.clone(), second.clone(), first, second));
73 };
74 let fourth = if let Ok(fourth) = input.try_parse(|i| parse(i)) {
75 fourth
76 } else {
77 return Ok(Self::new(first, second.clone(), third, second));
79 };
80 Ok(Self::new(first, second, third, fourth))
82 }
83}
84
85impl<'i, T> Parse<'i> for Rect<T>
86where
87 T: Clone + PartialEq + Parse<'i>,
88{
89 fn parse<'t>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i, ParserError<'i>>> {
90 Self::parse_with(input, T::parse)
91 }
92}
93
94impl<T> ToCss for Rect<T>
95where
96 T: PartialEq + ToCss,
97{
98 fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
99 where
100 W: std::fmt::Write,
101 {
102 self.0.to_css(dest)?;
103 let same_vertical = self.0 == self.2;
104 let same_horizontal = self.1 == self.3;
105 if same_vertical && same_horizontal && self.0 == self.1 {
106 return Ok(());
107 }
108 dest.write_str(" ")?;
109 self.1.to_css(dest)?;
110 if same_vertical && same_horizontal {
111 return Ok(());
112 }
113 dest.write_str(" ")?;
114 self.2.to_css(dest)?;
115 if same_horizontal {
116 return Ok(());
117 }
118 dest.write_str(" ")?;
119 self.3.to_css(dest)
120 }
121}
122
123impl<T: IsCompatible> IsCompatible for Rect<T> {
124 fn is_compatible(&self, browsers: crate::targets::Browsers) -> bool {
125 self.0.is_compatible(browsers)
126 && self.1.is_compatible(browsers)
127 && self.2.is_compatible(browsers)
128 && self.3.is_compatible(browsers)
129 }
130}