1use crate::{AngleOrZero, Length, LengthPercentage, NoneOr, NumberOrPercentage};
2use css_parse::{Function, T, function_set};
3use csskit_derives::{Parse, Peek, ToCursors, ToSpan, Visitable};
4
5#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
7#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
8#[allow(clippy::large_enum_variant)] #[visit]
10pub enum TransformFunction {
11 Matrix(MatrixFunction),
12 Matrix3d(Matrix3dFunction),
13 Translate(TranslateFunction),
14 Translate3d(Translate3dFunction),
15 TranslateX(TranslatexFunction),
16 TranslateY(TranslateyFunction),
17 TranslateZ(TranslatezFunction),
18 Scale(ScaleFunction),
19 Scale3d(Scale3dFunction),
20 ScaleX(ScalexFunction),
21 ScaleY(ScaleyFunction),
22 ScaleZ(ScalezFunction),
23 Rotate(RotateFunction),
24 Rotate3d(Rotate3dFunction),
25 RotateX(RotatexFunction),
26 RotateY(RotateyFunction),
27 RotateZ(RotatezFunction),
28 Skew(SkewFunction),
29 SkewX(SkewxFunction),
30 SkewY(SkewyFunction),
31 Perspective(PerspectiveFunction),
32}
33
34function_set!(pub struct MatrixFunctionName "matrix");
35
36#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
42#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
43#[visit(self)]
44pub struct MatrixFunction(pub Function<MatrixFunctionName, MatrixFunctionParams>);
45
46#[derive(Parse, Peek, ToCursors, ToSpan, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
47#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
48pub struct MatrixFunctionParams(
49 pub T![Number],
50 pub Option<T![,]>,
51 pub T![Number],
52 pub Option<T![,]>,
53 pub T![Number],
54 pub Option<T![,]>,
55 pub T![Number],
56 pub Option<T![,]>,
57 pub T![Number],
58 pub Option<T![,]>,
59 pub T![Number],
60);
61
62function_set!(pub struct Matrix3dFunctionName "matrix3d");
63
64#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
70#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
71#[visit(self)]
72pub struct Matrix3dFunction(pub Function<Matrix3dFunctionName, Matrix3dFunctionParams>);
73
74#[derive(Parse, Peek, ToCursors, ToSpan, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
75#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
76#[allow(clippy::type_complexity)] pub struct Matrix3dFunctionParams(
78 pub T![Number],
79 pub Option<T![,]>,
80 pub T![Number],
81 pub Option<T![,]>,
82 pub T![Number],
83 pub Option<T![,]>,
84 pub T![Number],
85 pub Option<T![,]>,
86 pub T![Number],
87 pub Option<T![,]>,
88 pub T![Number],
89 pub Option<T![,]>,
90 pub T![Number],
91 pub Option<T![,]>,
92 pub T![Number],
93 pub Option<T![,]>,
94 pub T![Number],
95 pub Option<T![,]>,
96 pub T![Number],
97 pub Option<T![,]>,
98 pub T![Number],
99 pub Option<T![,]>,
100 pub T![Number],
101 pub Option<T![,]>,
102 pub T![Number],
103 pub Option<T![,]>,
104 pub T![Number],
105 pub Option<T![,]>,
106 pub T![Number],
107 pub Option<T![,]>,
108 pub T![Number],
109);
110
111function_set!(pub struct TranslateFunctionName "translate");
112
113#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
119#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
120#[visit(self)]
121pub struct TranslateFunction(
122 pub Function<TranslateFunctionName, (LengthPercentage, Option<T![,]>, Option<LengthPercentage>)>,
123);
124
125function_set!(pub struct Translate3dFunctionName "translate3d");
126
127#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
133#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
134#[visit(self)]
135pub struct Translate3dFunction(pub Function<Translate3dFunctionName, Translate3dFunctionParams>);
136
137#[derive(Parse, Peek, ToCursors, ToSpan, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
138#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
139pub struct Translate3dFunctionParams(
140 pub LengthPercentage,
141 pub Option<T![,]>,
142 pub LengthPercentage,
143 pub Option<T![,]>,
144 pub Length,
145);
146
147function_set!(pub struct TranslatexFunctionName "translatex");
148
149#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
155#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
156#[visit(self)]
157pub struct TranslatexFunction(pub Function<TranslatexFunctionName, LengthPercentage>);
158
159function_set!(pub struct TranslateyFunctionName "translatey");
160
161#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
167#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
168#[visit(self)]
169pub struct TranslateyFunction(pub Function<TranslateyFunctionName, LengthPercentage>);
170
171function_set!(pub struct TranslatezFunctionName "translatez");
172
173#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
179#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
180#[visit(self)]
181pub struct TranslatezFunction(pub Function<TranslatezFunctionName, Length>);
182
183function_set!(pub struct ScaleFunctionName "scale");
184
185#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
191#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
192#[visit(self)]
193pub struct ScaleFunction(
194 pub Function<ScaleFunctionName, (NumberOrPercentage, Option<T![,]>, Option<NumberOrPercentage>)>,
195);
196
197function_set!(pub struct Scale3dFunctionName "scale3d");
198
199#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
205#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
206#[visit(self)]
207pub struct Scale3dFunction(pub Function<Scale3dFunctionName, Scale3dFunctionParams>);
208
209#[derive(Parse, Peek, ToCursors, ToSpan, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
210#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
211pub struct Scale3dFunctionParams(
212 pub NumberOrPercentage,
213 pub Option<T![,]>,
214 pub NumberOrPercentage,
215 pub Option<T![,]>,
216 pub NumberOrPercentage,
217);
218
219function_set!(pub struct ScalexFunctionName "scalex");
220
221#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
227#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
228#[visit(self)]
229pub struct ScalexFunction(pub Function<ScalexFunctionName, NumberOrPercentage>);
230
231function_set!(pub struct ScaleyFunctionName "scaley");
232
233#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
239#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
240#[visit(self)]
241pub struct ScaleyFunction(pub Function<ScaleyFunctionName, NumberOrPercentage>);
242
243function_set!(pub struct ScalezFunctionName "scalez");
244
245#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
251#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
252#[visit(self)]
253pub struct ScalezFunction(pub Function<ScalezFunctionName, NumberOrPercentage>);
254
255function_set!(pub struct RotateFunctionName "rotate");
256
257#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
263#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
264#[visit(self)]
265pub struct RotateFunction(pub Function<RotateFunctionName, AngleOrZero>);
266
267function_set!(pub struct Rotate3dFunctionName "rotate3d");
268
269#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
275#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
276#[visit(self)]
277pub struct Rotate3dFunction(pub Function<Rotate3dFunctionName, Rotate3dFunctionParams>);
278
279#[derive(Parse, Peek, ToCursors, ToSpan, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
280#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
281pub struct Rotate3dFunctionParams(
282 pub T![Number],
283 pub Option<T![,]>,
284 pub T![Number],
285 pub Option<T![,]>,
286 pub T![Number],
287 pub Option<T![,]>,
288 pub AngleOrZero,
289);
290
291function_set!(pub struct RotatexFunctionName "rotatex");
292
293#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
299#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
300#[visit(self)]
301pub struct RotatexFunction(pub Function<RotatexFunctionName, AngleOrZero>);
302
303function_set!(pub struct RotateyFunctionName "rotatey");
304
305#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
311#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
312#[visit(self)]
313pub struct RotateyFunction(pub Function<RotateyFunctionName, AngleOrZero>);
314
315function_set!(pub struct RotatezFunctionName "rotatez");
316
317#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
323#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
324#[visit(self)]
325pub struct RotatezFunction(pub Function<RotatezFunctionName, AngleOrZero>);
326
327function_set!(pub struct SkewFunctionName "skew");
328
329#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
335#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
336#[visit(self)]
337pub struct SkewFunction(pub Function<SkewFunctionName, (AngleOrZero, Option<T![,]>, Option<AngleOrZero>)>);
338
339function_set!(pub struct SkewxFunctionName "skewx");
340
341#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
347#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
348#[visit(self)]
349pub struct SkewxFunction(pub Function<SkewxFunctionName, AngleOrZero>);
350
351function_set!(pub struct SkewyFunctionName "skewy");
352
353#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
359#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
360#[visit(self)]
361pub struct SkewyFunction(pub Function<SkewyFunctionName, AngleOrZero>);
362
363function_set!(pub struct PerspectiveFunctionName "perspective");
364
365#[derive(Parse, Peek, ToCursors, ToSpan, Visitable, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
371#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
372#[visit(self)]
373pub struct PerspectiveFunction(pub Function<PerspectiveFunctionName, NoneOr<Length>>);
374
375#[cfg(test)]
376mod tests {
377 use super::*;
378 use css_parse::{assert_parse, assert_parse_error, assert_parse_span};
379
380 #[test]
381 fn size_test() {
382 assert_eq!(std::mem::size_of::<TransformFunction>(), 460);
383 }
384
385 #[test]
386 fn test_writes() {
387 assert_parse!(TransformFunction, "matrix(1,2,3,4,5,6)");
388 assert_parse!(TransformFunction, "matrix(1 2 3 4 5 6)");
389 assert_parse!(TransformFunction, "matrix(0,0,0,0,0,0)");
390 assert_parse!(TransformFunction, "matrix(-1,-2,-3,-4,-5,-6)");
391 assert_parse!(TransformFunction, "matrix(1.5,2.5,3.5,4.5,5.5,6.5)");
392
393 assert_parse!(TransformFunction, "translate(10px)");
394 assert_parse!(TransformFunction, "translate(10px,20px)");
395 assert_parse!(TransformFunction, "translate(45%)");
396 assert_parse!(TransformFunction, "translate(2rem)");
397 assert_parse!(TransformFunction, "translateX(1rem)");
398 assert_parse!(TransformFunction, "translateY(1rem)");
399
400 assert_parse!(TransformFunction, "scale(1,2)");
401 assert_parse!(TransformFunction, "scale(0,0)");
402 assert_parse!(TransformFunction, "scale(1)");
403 assert_parse!(TransformFunction, "scale(1.5,2.5)");
404 assert_parse!(TransformFunction, "scaleX(2)");
405 assert_parse!(TransformFunction, "scaleY(2)");
406
407 assert_parse!(TransformFunction, "rotate(45deg)");
408 assert_parse!(TransformFunction, "rotate(0)");
409 assert_parse!(TransformFunction, "rotate(2turn)");
410 assert_parse!(TransformFunction, "rotate(20rad");
411
412 assert_parse!(TransformFunction, "skew(1deg,2deg)");
413 assert_parse!(TransformFunction, "skew(0,0)");
414 assert_parse!(TransformFunction, "skew(1deg)");
415 assert_parse!(TransformFunction, "skewX(1deg)");
416 assert_parse!(TransformFunction, "skewX(0)");
417 assert_parse!(TransformFunction, "skewY(1deg)");
418 assert_parse!(TransformFunction, "skewY(0)");
419
420 assert_parse!(TransformFunction, "scale3d(10%,10%,10%)");
421 assert_parse!(TransformFunction, "rotate3d(1,2,3,10deg)");
422 }
423
424 #[test]
425 fn test_span() {
426 assert_parse_span!(
427 TransformFunction,
428 r#"
429 matrix(1,2,3,4,5,6) translate(0)
430 ^^^^^^^^^^^^^^^^^^^
431 "#
432 );
433 assert_parse_span!(
434 TransformFunction,
435 r#"
436 translate(0) foo
437 ^^^^^^^^^^^^
438 "#
439 );
440 assert_parse_span!(
441 TranslateFunction,
442 r#"
443 translate(0) bar
444 ^^^^^^^^^^^^
445 "#
446 );
447 }
448
449 #[test]
450 fn test_errors() {
451 assert_parse_error!(TransformFunction, "matrix()");
452 assert_parse_error!(TransformFunction, "matrix(1)");
453 assert_parse_error!(TransformFunction, "matrix(1,2)");
454 assert_parse_error!(TransformFunction, "matrix(one,two,three,four,five,size)");
455
456 assert_parse_error!(TransformFunction, "translate()");
457 assert_parse_error!(TransformFunction, "translate(foo)");
458 assert_parse_error!(TransformFunction, "translateX()");
459 assert_parse_error!(TransformFunction, "translateX(foo)");
460 assert_parse_error!(TransformFunction, "translateY()");
461 assert_parse_error!(TransformFunction, "translateY(foo)");
462
463 assert_parse_error!(TransformFunction, "scale()");
464 assert_parse_error!(TransformFunction, "scale(foo)");
465 assert_parse_error!(TransformFunction, "scaleX()");
466 assert_parse_error!(TransformFunction, "scaleX(foo)");
467 assert_parse_error!(TransformFunction, "scaleY()");
468 assert_parse_error!(TransformFunction, "scaleY(foo)");
469
470 assert_parse_error!(TransformFunction, "rotate()");
471 assert_parse_error!(TransformFunction, "rotate(45px)");
472 assert_parse_error!(TransformFunction, "rotate(all the way around)");
473
474 assert_parse_error!(TransformFunction, "skew()");
475 assert_parse_error!(TransformFunction, "skew(foo)");
476 assert_parse_error!(TransformFunction, "skewX()");
477 assert_parse_error!(TransformFunction, "skewX(foo)");
478 assert_parse_error!(TransformFunction, "skewY()");
479 assert_parse_error!(TransformFunction, "skewY(foo)");
480 }
481}