stylex_css_parser/properties/
transform.rs1use crate::{css_types::transform_function::TransformFunction, token_parser::TokenParser};
8use std::fmt::{self, Display};
9
10#[derive(Debug, Clone, PartialEq)]
12pub struct Transform {
13 pub value: Vec<TransformFunction>,
14}
15
16impl Transform {
17 pub fn new(value: Vec<TransformFunction>) -> Self {
19 Self { value }
20 }
21
22 pub fn parser() -> TokenParser<Transform> {
23 use crate::token_parser::tokens;
24
25 TokenParser::one_or_more_separated_by(TransformFunction::parse(), tokens::whitespace())
26 .map(Transform::new, Some("to_transform"))
27 }
28}
29
30impl Display for Transform {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 let function_strings: Vec<String> = self.value.iter().map(|func| func.to_string()).collect();
33 write!(f, "{}", function_strings.join(" "))
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40 use crate::css_types::{Angle, Length, LengthPercentage, Percentage, transform_function::*};
41
42 #[test]
43 fn test_transform_function_creation() {
44 let translate = TransformFunction::TranslateAxis(TranslateAxis::new(
45 LengthPercentage::Length(Length::new(10.0, "px".to_string())),
46 Axis::X,
47 ));
48
49 assert!(matches!(translate, TransformFunction::TranslateAxis(_)));
51 }
52
53 #[test]
54 fn test_transform_function_display() {
55 let translate_x = TransformFunction::TranslateAxis(TranslateAxis::new(
56 LengthPercentage::Length(Length::new(10.0, "px".to_string())),
57 Axis::X,
58 ));
59 assert_eq!(translate_x.to_string(), "translateX(10px)");
60
61 let translate = TransformFunction::Translate(Translate::new(
62 LengthPercentage::Length(Length::new(10.0, "px".to_string())),
63 Some(LengthPercentage::Length(Length::new(
64 20.0,
65 "px".to_string(),
66 ))),
67 ));
68 assert_eq!(translate.to_string(), "translate(10px, 20px)");
69
70 let rotate = TransformFunction::Rotate(Rotate::new(Angle::new(45.0, "deg".to_string())));
71 assert_eq!(rotate.to_string(), "rotate(45deg)");
72 }
73
74 #[test]
75 fn test_transform_creation() {
76 let func1 = TransformFunction::TranslateAxis(TranslateAxis::new(
77 LengthPercentage::Length(Length::new(10.0, "px".to_string())),
78 Axis::X,
79 ));
80 let func2 = TransformFunction::Rotate(Rotate::new(Angle::new(45.0, "deg".to_string())));
81
82 let transform = Transform::new(vec![func1, func2]);
83 assert_eq!(transform.value.len(), 2);
84 }
85
86 #[test]
87 fn test_transform_display() {
88 let func1 = TransformFunction::TranslateAxis(TranslateAxis::new(
89 LengthPercentage::Length(Length::new(10.0, "px".to_string())),
90 Axis::X,
91 ));
92 let func2 = TransformFunction::Rotate(Rotate::new(Angle::new(45.0, "deg".to_string())));
93
94 let transform = Transform::new(vec![func1, func2]);
95 assert_eq!(transform.to_string(), "translateX(10px) rotate(45deg)");
96 }
97
98 #[test]
99 fn test_transform_empty() {
100 let transform = Transform::new(vec![]);
101 assert_eq!(transform.to_string(), "");
102 }
103
104 #[test]
105 fn test_transform_equality() {
106 let func = TransformFunction::ScaleAxis(ScaleAxis::new(1.5, Axis::X));
107
108 let transform1 = Transform::new(vec![func.clone()]);
109 let transform2 = Transform::new(vec![func]);
110
111 assert_eq!(transform1, transform2);
112 }
113
114 #[test]
115 fn test_transform_parser_creation() {
116 let _parser = Transform::parser();
118 }
119
120 #[test]
121 fn test_transform_single_function() {
122 let transform = Transform::new(vec![
123 TransformFunction::Translate(Translate::new(
124 LengthPercentage::Percentage(Percentage::new(50.0)),
125 Some(LengthPercentage::Percentage(Percentage::new(-50.0))),
126 )),
127 TransformFunction::Rotate(Rotate::new(Angle::new(45.0, "deg".to_string()))),
128 TransformFunction::Scale(Scale::new(1.2, Some(1.2))),
129 ]);
130
131 assert_eq!(transform.value.len(), 3);
132 assert!(transform.to_string().contains("translate(50%, -50%)"));
133 assert!(transform.to_string().contains("rotate(45deg)"));
134 assert!(transform.to_string().contains("scale(1.2, 1.2)"));
135 }
136
137 #[test]
138 fn test_transform_complex_combination() {
139 let func1 = TransformFunction::Translate(Translate::new(
140 LengthPercentage::Length(Length::new(10.0, "px".to_string())),
141 Some(LengthPercentage::Length(Length::new(
142 20.0,
143 "px".to_string(),
144 ))),
145 ));
146 let func2 = TransformFunction::Rotate(Rotate::new(Angle::new(45.0, "deg".to_string())));
147 let func3 = TransformFunction::Scale(Scale::new(1.2, Some(1.2)));
148
149 let transform = Transform::new(vec![func1, func2, func3]);
150 assert_eq!(transform.value.len(), 3);
151 assert_eq!(
152 transform.to_string(),
153 "translate(10px, 20px) rotate(45deg) scale(1.2, 1.2)"
154 );
155 }
156
157 #[test]
158 fn test_transform_common_functions() {
159 let translate = TransformFunction::Translate(Translate::new(
161 LengthPercentage::Length(Length::new(10.0, "px".to_string())),
162 Some(LengthPercentage::Length(Length::new(
163 20.0,
164 "px".to_string(),
165 ))),
166 ));
167
168 let rotate = TransformFunction::Rotate(Rotate::new(Angle::new(45.0, "deg".to_string())));
169
170 let scale = TransformFunction::Scale(Scale::new(1.5, Some(1.5)));
171
172 let skew = TransformFunction::Skew(Skew::new(
173 Angle::new(10.0, "deg".to_string()),
174 Some(Angle::new(20.0, "deg".to_string())),
175 ));
176
177 let functions = vec![translate, rotate, scale, skew];
178 let transform = Transform::new(functions);
179
180 assert_eq!(transform.value.len(), 4);
181 assert!(transform.to_string().contains("translate"));
182 assert!(transform.to_string().contains("rotate"));
183 assert!(transform.to_string().contains("scale"));
184 assert!(transform.to_string().contains("skew"));
185 }
186}