1use crate::context::PropertyHandlerContext;
4use crate::declaration::{DeclarationBlock, DeclarationList};
5use crate::error::{ParserError, PrinterError};
6use crate::printer::Printer;
7use crate::properties::{Property, PropertyId};
8use crate::stylesheet::{ParserOptions, PrinterOptions};
9use crate::targets::Browsers;
10use crate::vendor_prefix::VendorPrefix;
11use cssparser::*;
12
13pub trait Parse<'i>: Sized {
15 fn parse<'t>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i, ParserError<'i>>>;
17
18 fn parse_string(input: &'i str) -> Result<Self, ParseError<'i, ParserError<'i>>> {
22 let mut input = ParserInput::new(input);
23 let mut parser = Parser::new(&mut input);
24 let result = Self::parse(&mut parser)?;
25 parser.expect_exhausted()?;
26 Ok(result)
27 }
28}
29
30pub(crate) trait ParseWithOptions<'i>: Sized {
31 fn parse_with_options<'t>(
32 input: &mut Parser<'i, 't>,
33 options: &ParserOptions,
34 ) -> Result<Self, ParseError<'i, ParserError<'i>>>;
35}
36
37impl<'i, T: Parse<'i>> ParseWithOptions<'i> for T {
38 #[inline]
39 fn parse_with_options<'t>(
40 input: &mut Parser<'i, 't>,
41 _options: &ParserOptions,
42 ) -> Result<Self, ParseError<'i, ParserError<'i>>> {
43 T::parse(input)
44 }
45}
46
47pub trait ToCss {
49 fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
51 where
52 W: std::fmt::Write;
53
54 #[inline]
58 fn to_css_string(&self, options: PrinterOptions) -> Result<String, PrinterError> {
59 let mut s = String::new();
60 let mut printer = Printer::new(&mut s, options);
61 self.to_css(&mut printer)?;
62 Ok(s)
63 }
64}
65
66impl<'a, T> ToCss for &'a T
67where
68 T: ToCss + ?Sized,
69{
70 fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
71 where
72 W: std::fmt::Write,
73 {
74 (*self).to_css(dest)
75 }
76}
77
78pub(crate) trait PropertyHandler<'i>: Sized {
79 fn handle_property(
80 &mut self,
81 property: &Property<'i>,
82 dest: &mut DeclarationList<'i>,
83 context: &mut PropertyHandlerContext<'i, '_>,
84 ) -> bool;
85 fn finalize(&mut self, dest: &mut DeclarationList<'i>, context: &mut PropertyHandlerContext<'i, '_>);
86}
87
88pub(crate) mod private {
89 pub trait TryAdd<T> {
90 fn try_add(&self, other: &T) -> Option<T>;
91 }
92
93 pub trait AddInternal {
94 fn add(self, other: Self) -> Self;
95 }
96}
97
98pub(crate) trait FromStandard<T>: Sized {
99 fn from_standard(val: &T) -> Option<Self>;
100}
101
102pub(crate) trait FallbackValues: Sized {
103 fn get_fallbacks(&mut self, targets: Browsers) -> Vec<Self>;
104}
105
106pub(crate) trait Shorthand<'i>: Sized {
108 fn from_longhands(decls: &DeclarationBlock<'i>, vendor_prefix: VendorPrefix) -> Option<(Self, bool)>;
110
111 fn longhands(vendor_prefix: VendorPrefix) -> Vec<PropertyId<'static>>;
113
114 fn longhand(&self, property_id: &PropertyId) -> Option<Property<'i>>;
116
117 fn set_longhand(&mut self, property: &Property<'i>) -> Result<(), ()>;
119}
120
121pub trait Op {
123 fn op<F: FnOnce(f32, f32) -> f32>(&self, rhs: &Self, op: F) -> Self;
125 fn op_to<T, F: FnOnce(f32, f32) -> T>(&self, rhs: &Self, op: F) -> T;
127}
128
129macro_rules! impl_op {
130 ($t: ty, $trait: ident $(:: $x: ident)*, $op: ident) => {
131 impl $trait$(::$x)* for $t {
132 type Output = $t;
133
134 fn $op(self, rhs: Self) -> Self::Output {
135 self.op(&rhs, $trait$(::$x)*::$op)
136 }
137 }
138 };
139}
140
141pub(crate) use impl_op;
142
143pub trait TryOp: Sized {
145 fn try_op<F: FnOnce(f32, f32) -> f32>(&self, rhs: &Self, op: F) -> Option<Self>;
147 fn try_op_to<T, F: FnOnce(f32, f32) -> T>(&self, rhs: &Self, op: F) -> Option<T>;
149}
150
151impl<T: Op> TryOp for T {
152 fn try_op<F: FnOnce(f32, f32) -> f32>(&self, rhs: &Self, op: F) -> Option<Self> {
153 Some(self.op(rhs, op))
154 }
155
156 fn try_op_to<U, F: FnOnce(f32, f32) -> U>(&self, rhs: &Self, op: F) -> Option<U> {
157 Some(self.op_to(rhs, op))
158 }
159}
160
161pub trait Map {
163 fn map<F: FnOnce(f32) -> f32>(&self, op: F) -> Self;
165}
166
167pub trait TryMap: Sized {
169 fn try_map<F: FnOnce(f32) -> f32>(&self, op: F) -> Option<Self>;
171}
172
173impl<T: Map> TryMap for T {
174 fn try_map<F: FnOnce(f32) -> f32>(&self, op: F) -> Option<Self> {
175 Some(self.map(op))
176 }
177}
178
179pub trait Sign {
181 fn sign(&self) -> f32;
183
184 fn is_sign_positive(&self) -> bool {
186 f32::is_sign_positive(self.sign())
187 }
188
189 fn is_sign_negative(&self) -> bool {
191 f32::is_sign_negative(self.sign())
192 }
193}
194
195pub trait TrySign {
197 fn try_sign(&self) -> Option<f32>;
199
200 fn is_sign_positive(&self) -> bool {
202 self.try_sign().map_or(false, |s| f32::is_sign_positive(s))
203 }
204
205 fn is_sign_negative(&self) -> bool {
207 self.try_sign().map_or(false, |s| f32::is_sign_negative(s))
208 }
209}
210
211impl<T: Sign> TrySign for T {
212 fn try_sign(&self) -> Option<f32> {
213 Some(self.sign())
214 }
215}
216
217pub trait Zero {
219 fn zero() -> Self;
221
222 fn is_zero(&self) -> bool;
224}