1use super::prelude::*;
2use crate::{AngleOrZero, Length, LengthPercentage, NoneOr, NumberOrPercentage};
3
4#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
6#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
7#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
8#[derive(csskit_derives::NodeWithMetadata)]
9#[allow(clippy::large_enum_variant)] pub 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
34#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
40#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
41#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
42#[derive(csskit_derives::NodeWithMetadata)]
43pub struct MatrixFunction {
44 #[atom(CssAtomSet::Matrix)]
45 pub name: T![Function],
46 pub params: MatrixFunctionParams,
47 pub close: T![')'],
48}
49
50#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
51#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
52pub struct MatrixFunctionParams(
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 pub Option<T![,]>,
61 pub T![Number],
62 pub Option<T![,]>,
63 pub T![Number],
64);
65
66#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
72#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
73#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
74#[derive(csskit_derives::NodeWithMetadata)]
75pub struct Matrix3dFunction {
76 #[atom(CssAtomSet::Matrix3d)]
77 pub name: T![Function],
78 pub params: Matrix3dFunctionParams,
79 pub close: T![')'],
80}
81
82#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
83#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
84#[allow(clippy::type_complexity)] pub struct Matrix3dFunctionParams(
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 pub Option<T![,]>,
110 pub T![Number],
111 pub Option<T![,]>,
112 pub T![Number],
113 pub Option<T![,]>,
114 pub T![Number],
115 pub Option<T![,]>,
116 pub T![Number],
117);
118
119#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
125#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
126#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
127#[derive(csskit_derives::NodeWithMetadata)]
128pub struct TranslateFunction {
129 #[atom(CssAtomSet::Translate)]
130 pub name: T![Function],
131 pub x: LengthPercentage,
132 pub comma: Option<T![,]>,
133 pub y: Option<LengthPercentage>,
134 pub close: T![')'],
135}
136
137#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
143#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
144#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
145#[derive(csskit_derives::NodeWithMetadata)]
146pub struct Translate3dFunction {
147 #[atom(CssAtomSet::Translate3d)]
148 pub name: T![Function],
149 pub params: Translate3dFunctionParams,
150 pub close: T![')'],
151}
152
153#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
154#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
155pub struct Translate3dFunctionParams(
156 pub LengthPercentage,
157 pub Option<T![,]>,
158 pub LengthPercentage,
159 pub Option<T![,]>,
160 pub Length,
161);
162
163#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
169#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
170#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
171#[derive(csskit_derives::NodeWithMetadata)]
172pub struct TranslatexFunction {
173 #[atom(CssAtomSet::Translatex)]
174 pub name: T![Function],
175 pub params: LengthPercentage,
176 pub close: T![')'],
177}
178
179#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
185#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
186#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
187#[derive(csskit_derives::NodeWithMetadata)]
188pub struct TranslateyFunction {
189 #[atom(CssAtomSet::Translatey)]
190 pub name: T![Function],
191 pub params: LengthPercentage,
192 pub close: T![')'],
193}
194
195#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
201#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
202#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
203#[derive(csskit_derives::NodeWithMetadata)]
204pub struct TranslatezFunction {
205 #[atom(CssAtomSet::Translatez)]
206 pub name: T![Function],
207 pub params: Length,
208 pub close: T![')'],
209}
210
211#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
217#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
218#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
219#[derive(csskit_derives::NodeWithMetadata)]
220pub struct ScaleFunction {
221 #[atom(CssAtomSet::Scale)]
222 pub name: T![Function],
223 pub params: (NumberOrPercentage, Option<T![,]>, Option<NumberOrPercentage>),
224 pub close: T![')'],
225}
226
227#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
233#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
234#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
235#[derive(csskit_derives::NodeWithMetadata)]
236pub struct Scale3dFunction {
237 #[atom(CssAtomSet::Scale3d)]
238 pub name: T![Function],
239 pub params: Scale3dFunctionParams,
240 pub close: T![')'],
241}
242
243#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
244#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
245pub struct Scale3dFunctionParams(
246 pub NumberOrPercentage,
247 pub Option<T![,]>,
248 pub NumberOrPercentage,
249 pub Option<T![,]>,
250 pub NumberOrPercentage,
251);
252
253#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
259#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
260#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
261#[derive(csskit_derives::NodeWithMetadata)]
262pub struct ScalexFunction {
263 #[atom(CssAtomSet::Scalex)]
264 pub name: T![Function],
265 pub params: NumberOrPercentage,
266 pub close: T![')'],
267}
268
269#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
275#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
276#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
277#[derive(csskit_derives::NodeWithMetadata)]
278pub struct ScaleyFunction {
279 #[atom(CssAtomSet::Scaley)]
280 pub name: T![Function],
281 pub params: NumberOrPercentage,
282 pub close: T![')'],
283}
284
285#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
291#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
292#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
293#[derive(csskit_derives::NodeWithMetadata)]
294pub struct ScalezFunction {
295 #[atom(CssAtomSet::Scalez)]
296 pub name: T![Function],
297 pub params: NumberOrPercentage,
298 pub close: T![')'],
299}
300
301#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
307#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
308#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
309#[derive(csskit_derives::NodeWithMetadata)]
310pub struct RotateFunction {
311 #[atom(CssAtomSet::Rotate)]
312 pub name: T![Function],
313 pub params: AngleOrZero,
314 pub close: T![')'],
315}
316
317#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
323#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
324#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
325#[derive(csskit_derives::NodeWithMetadata)]
326pub struct Rotate3dFunction {
327 #[atom(CssAtomSet::Rotate3d)]
328 pub name: T![Function],
329 pub params: Rotate3dFunctionParams,
330 pub close: T![')'],
331}
332
333#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
334#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
335pub struct Rotate3dFunctionParams(
336 pub T![Number],
337 pub Option<T![,]>,
338 pub T![Number],
339 pub Option<T![,]>,
340 pub T![Number],
341 pub Option<T![,]>,
342 pub AngleOrZero,
343);
344
345#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
351#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
352#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
353#[derive(csskit_derives::NodeWithMetadata)]
354pub struct RotatexFunction {
355 #[atom(CssAtomSet::Rotatex)]
356 pub name: T![Function],
357 pub params: AngleOrZero,
358 pub close: T![')'],
359}
360
361#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
367#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
368#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
369#[derive(csskit_derives::NodeWithMetadata)]
370pub struct RotateyFunction {
371 #[atom(CssAtomSet::Rotatey)]
372 pub name: T![Function],
373 pub params: AngleOrZero,
374 pub close: T![')'],
375}
376
377#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
383#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
384#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
385#[derive(csskit_derives::NodeWithMetadata)]
386pub struct RotatezFunction {
387 #[atom(CssAtomSet::Rotatez)]
388 pub name: T![Function],
389 pub params: AngleOrZero,
390 pub close: T![')'],
391}
392
393#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
399#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
400#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
401#[derive(csskit_derives::NodeWithMetadata)]
402pub struct SkewFunction {
403 #[atom(CssAtomSet::Skew)]
404 pub name: T![Function],
405 pub params: (AngleOrZero, Option<T![,]>, Option<AngleOrZero>),
406 pub close: T![')'],
407}
408
409#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
415#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
416#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
417#[derive(csskit_derives::NodeWithMetadata)]
418pub struct SkewxFunction {
419 #[atom(CssAtomSet::Skewx)]
420 pub name: T![Function],
421 pub params: AngleOrZero,
422 pub close: T![')'],
423}
424
425#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
431#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
432#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
433#[derive(csskit_derives::NodeWithMetadata)]
434pub struct SkewyFunction {
435 #[atom(CssAtomSet::Skewy)]
436 pub name: T![Function],
437 pub params: AngleOrZero,
438 pub close: T![')'],
439}
440
441#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
447#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
448#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
449#[derive(csskit_derives::NodeWithMetadata)]
450pub struct PerspectiveFunction {
451 #[atom(CssAtomSet::Perspective)]
452 pub name: T![Function],
453 pub params: NoneOr<Length>,
454 pub close: T![')'],
455}
456
457#[cfg(test)]
458mod tests {
459 use super::*;
460 use crate::CssAtomSet;
461 use css_parse::{assert_parse, assert_parse_error, assert_parse_span};
462
463 #[test]
464 fn size_test() {
465 assert_eq!(std::mem::size_of::<TransformFunction>(), 456);
466 }
467
468 #[test]
469 fn test_writes() {
470 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(1,2,3,4,5,6)");
471 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(1 2 3 4 5 6)");
472 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(0,0,0,0,0,0)");
473 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(-1,-2,-3,-4,-5,-6)");
474 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "matrix(1.5,2.5,3.5,4.5,5.5,6.5)");
475
476 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(10px)");
477 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(10px,20px)");
478 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(45%)");
479 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translate(2rem)");
480 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translateX(1rem)");
481 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "translateY(1rem)");
482
483 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(1,2)");
484 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(0,0)");
485 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(1)");
486 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale(1.5,2.5)");
487 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scaleX(2)");
488 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scaleY(2)");
489
490 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(45deg)");
491 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(0)");
492 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(2turn)");
493 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate(20rad)");
494
495 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skew(1deg,2deg)");
496 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skew(0,0)");
497 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skew(1deg)");
498 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewX(1deg)");
499 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewX(0)");
500 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewY(1deg)");
501 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "skewY(0)");
502
503 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "scale3d(10%,10%,10%)");
504 assert_parse!(CssAtomSet::ATOMS, TransformFunction, "rotate3d(1,2,3,10deg)");
505 }
506
507 #[test]
508 fn test_span() {
509 assert_parse_span!(
510 CssAtomSet::ATOMS,
511 TransformFunction,
512 r#"
513 matrix(1,2,3,4,5,6) translate(0)
514 ^^^^^^^^^^^^^^^^^^^
515 "#
516 );
517 assert_parse_span!(
518 CssAtomSet::ATOMS,
519 TransformFunction,
520 r#"
521 translate(0) foo
522 ^^^^^^^^^^^^
523 "#
524 );
525 assert_parse_span!(
526 CssAtomSet::ATOMS,
527 TranslateFunction,
528 r#"
529 translate(0) bar
530 ^^^^^^^^^^^^
531 "#
532 );
533 }
534
535 #[test]
536 fn test_errors() {
537 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "matrix()");
538 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "matrix(1)");
539 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "matrix(1,2)");
540 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "matrix(one,two,three,four,five,size)");
541
542 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translate()");
543 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translate(foo)");
544 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translateX()");
545 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translateX(foo)");
546 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translateY()");
547 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "translateY(foo)");
548
549 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scale()");
550 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scale(foo)");
551 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scaleX()");
552 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scaleX(foo)");
553 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scaleY()");
554 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "scaleY(foo)");
555
556 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "rotate()");
557 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "rotate(45px)");
558 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "rotate(all the way around)");
559
560 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skew()");
561 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skew(foo)");
562 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skewX()");
563 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skewX(foo)");
564 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skewY()");
565 assert_parse_error!(CssAtomSet::ATOMS, TransformFunction, "skewY(foo)");
566 }
567}