tailwind_rs_core/utilities/effects/
blend_modes.rs1use crate::classes::ClassBuilder;
6use serde::{Deserialize, Serialize};
7use std::fmt;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
11pub enum MixBlendMode {
12 Normal,
14 Multiply,
16 Screen,
18 Overlay,
20 Darken,
22 Lighten,
24 ColorDodge,
26 ColorBurn,
28 HardLight,
30 SoftLight,
32 Difference,
34 Exclusion,
36 Hue,
38 Saturation,
40 Color,
42 Luminosity,
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
48pub enum BackgroundBlendMode {
49 Normal,
51 Multiply,
53 Screen,
55 Overlay,
57 Darken,
59 Lighten,
61 ColorDodge,
63 ColorBurn,
65 HardLight,
67 SoftLight,
69 Difference,
71 Exclusion,
73 Hue,
75 Saturation,
77 Color,
79 Luminosity,
81}
82
83impl fmt::Display for MixBlendMode {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 match self {
86 MixBlendMode::Normal => write!(f, "mix-blend-normal"),
87 MixBlendMode::Multiply => write!(f, "mix-blend-multiply"),
88 MixBlendMode::Screen => write!(f, "mix-blend-screen"),
89 MixBlendMode::Overlay => write!(f, "mix-blend-overlay"),
90 MixBlendMode::Darken => write!(f, "mix-blend-darken"),
91 MixBlendMode::Lighten => write!(f, "mix-blend-lighten"),
92 MixBlendMode::ColorDodge => write!(f, "mix-blend-color-dodge"),
93 MixBlendMode::ColorBurn => write!(f, "mix-blend-color-burn"),
94 MixBlendMode::HardLight => write!(f, "mix-blend-hard-light"),
95 MixBlendMode::SoftLight => write!(f, "mix-blend-soft-light"),
96 MixBlendMode::Difference => write!(f, "mix-blend-difference"),
97 MixBlendMode::Exclusion => write!(f, "mix-blend-exclusion"),
98 MixBlendMode::Hue => write!(f, "mix-blend-hue"),
99 MixBlendMode::Saturation => write!(f, "mix-blend-saturation"),
100 MixBlendMode::Color => write!(f, "mix-blend-color"),
101 MixBlendMode::Luminosity => write!(f, "mix-blend-luminosity"),
102 }
103 }
104}
105
106impl fmt::Display for BackgroundBlendMode {
107 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108 match self {
109 BackgroundBlendMode::Normal => write!(f, "bg-blend-normal"),
110 BackgroundBlendMode::Multiply => write!(f, "bg-blend-multiply"),
111 BackgroundBlendMode::Screen => write!(f, "bg-blend-screen"),
112 BackgroundBlendMode::Overlay => write!(f, "bg-blend-overlay"),
113 BackgroundBlendMode::Darken => write!(f, "bg-blend-darken"),
114 BackgroundBlendMode::Lighten => write!(f, "bg-blend-lighten"),
115 BackgroundBlendMode::ColorDodge => write!(f, "bg-blend-color-dodge"),
116 BackgroundBlendMode::ColorBurn => write!(f, "bg-blend-color-burn"),
117 BackgroundBlendMode::HardLight => write!(f, "bg-blend-hard-light"),
118 BackgroundBlendMode::SoftLight => write!(f, "bg-blend-soft-light"),
119 BackgroundBlendMode::Difference => write!(f, "bg-blend-difference"),
120 BackgroundBlendMode::Exclusion => write!(f, "bg-blend-exclusion"),
121 BackgroundBlendMode::Hue => write!(f, "bg-blend-hue"),
122 BackgroundBlendMode::Saturation => write!(f, "bg-blend-saturation"),
123 BackgroundBlendMode::Color => write!(f, "bg-blend-color"),
124 BackgroundBlendMode::Luminosity => write!(f, "bg-blend-luminosity"),
125 }
126 }
127}
128
129pub trait MixBlendModeUtilities {
131 fn mix_blend_mode(self, mode: MixBlendMode) -> Self;
132}
133
134pub trait BackgroundBlendModeUtilities {
136 fn background_blend_mode(self, mode: BackgroundBlendMode) -> Self;
137}
138
139impl MixBlendModeUtilities for ClassBuilder {
140 fn mix_blend_mode(self, mode: MixBlendMode) -> Self {
141 self.class(mode.to_string())
142 }
143}
144
145impl BackgroundBlendModeUtilities for ClassBuilder {
146 fn background_blend_mode(self, mode: BackgroundBlendMode) -> Self {
147 self.class(mode.to_string())
148 }
149}
150
151#[cfg(test)]
152mod tests {
153 use super::*;
154
155 #[test]
156 fn test_mix_blend_mode_display() {
157 assert_eq!(MixBlendMode::Normal.to_string(), "mix-blend-normal");
158 assert_eq!(MixBlendMode::Multiply.to_string(), "mix-blend-multiply");
159 assert_eq!(MixBlendMode::Screen.to_string(), "mix-blend-screen");
160 assert_eq!(MixBlendMode::Overlay.to_string(), "mix-blend-overlay");
161 assert_eq!(MixBlendMode::Darken.to_string(), "mix-blend-darken");
162 assert_eq!(MixBlendMode::Lighten.to_string(), "mix-blend-lighten");
163 assert_eq!(
164 MixBlendMode::ColorDodge.to_string(),
165 "mix-blend-color-dodge"
166 );
167 assert_eq!(MixBlendMode::ColorBurn.to_string(), "mix-blend-color-burn");
168 assert_eq!(MixBlendMode::HardLight.to_string(), "mix-blend-hard-light");
169 assert_eq!(MixBlendMode::SoftLight.to_string(), "mix-blend-soft-light");
170 assert_eq!(MixBlendMode::Difference.to_string(), "mix-blend-difference");
171 assert_eq!(MixBlendMode::Exclusion.to_string(), "mix-blend-exclusion");
172 assert_eq!(MixBlendMode::Hue.to_string(), "mix-blend-hue");
173 assert_eq!(MixBlendMode::Saturation.to_string(), "mix-blend-saturation");
174 assert_eq!(MixBlendMode::Color.to_string(), "mix-blend-color");
175 assert_eq!(MixBlendMode::Luminosity.to_string(), "mix-blend-luminosity");
176 }
177
178 #[test]
179 fn test_background_blend_mode_display() {
180 assert_eq!(BackgroundBlendMode::Normal.to_string(), "bg-blend-normal");
181 assert_eq!(
182 BackgroundBlendMode::Multiply.to_string(),
183 "bg-blend-multiply"
184 );
185 assert_eq!(BackgroundBlendMode::Screen.to_string(), "bg-blend-screen");
186 assert_eq!(BackgroundBlendMode::Overlay.to_string(), "bg-blend-overlay");
187 assert_eq!(BackgroundBlendMode::Darken.to_string(), "bg-blend-darken");
188 assert_eq!(BackgroundBlendMode::Lighten.to_string(), "bg-blend-lighten");
189 assert_eq!(
190 BackgroundBlendMode::ColorDodge.to_string(),
191 "bg-blend-color-dodge"
192 );
193 assert_eq!(
194 BackgroundBlendMode::ColorBurn.to_string(),
195 "bg-blend-color-burn"
196 );
197 assert_eq!(
198 BackgroundBlendMode::HardLight.to_string(),
199 "bg-blend-hard-light"
200 );
201 assert_eq!(
202 BackgroundBlendMode::SoftLight.to_string(),
203 "bg-blend-soft-light"
204 );
205 assert_eq!(
206 BackgroundBlendMode::Difference.to_string(),
207 "bg-blend-difference"
208 );
209 assert_eq!(
210 BackgroundBlendMode::Exclusion.to_string(),
211 "bg-blend-exclusion"
212 );
213 assert_eq!(BackgroundBlendMode::Hue.to_string(), "bg-blend-hue");
214 assert_eq!(
215 BackgroundBlendMode::Saturation.to_string(),
216 "bg-blend-saturation"
217 );
218 assert_eq!(BackgroundBlendMode::Color.to_string(), "bg-blend-color");
219 assert_eq!(
220 BackgroundBlendMode::Luminosity.to_string(),
221 "bg-blend-luminosity"
222 );
223 }
224
225 #[test]
226 fn test_mix_blend_mode_utilities() {
227 let classes = ClassBuilder::new()
228 .mix_blend_mode(MixBlendMode::Multiply)
229 .build();
230
231 assert!(classes.to_css_classes().contains("mix-blend-multiply"));
232 }
233
234 #[test]
235 fn test_background_blend_mode_utilities() {
236 let classes = ClassBuilder::new()
237 .background_blend_mode(BackgroundBlendMode::Screen)
238 .build();
239
240 assert!(classes.to_css_classes().contains("bg-blend-screen"));
241 }
242
243 #[test]
244 fn test_blend_mode_serialization() {
245 let mix_blend_mode = MixBlendMode::Overlay;
246 let serialized = serde_json::to_string(&mix_blend_mode).unwrap();
247 let deserialized: MixBlendMode = serde_json::from_str(&serialized).unwrap();
248 assert_eq!(mix_blend_mode, deserialized);
249
250 let background_blend_mode = BackgroundBlendMode::Overlay;
251 let serialized = serde_json::to_string(&background_blend_mode).unwrap();
252 let deserialized: BackgroundBlendMode = serde_json::from_str(&serialized).unwrap();
253 assert_eq!(background_blend_mode, deserialized);
254 }
255
256 #[test]
257 fn test_blend_mode_equality_and_hash() {
258 let mix_blend_mode1 = MixBlendMode::Multiply;
259 let mix_blend_mode2 = MixBlendMode::Multiply;
260 let mix_blend_mode3 = MixBlendMode::Screen;
261
262 assert_eq!(mix_blend_mode1, mix_blend_mode2);
263 assert_ne!(mix_blend_mode1, mix_blend_mode3);
264
265 let background_blend_mode1 = BackgroundBlendMode::Multiply;
266 let background_blend_mode2 = BackgroundBlendMode::Multiply;
267 let background_blend_mode3 = BackgroundBlendMode::Screen;
268
269 assert_eq!(background_blend_mode1, background_blend_mode2);
270 assert_ne!(background_blend_mode1, background_blend_mode3);
271
272 use std::collections::hash_map::DefaultHasher;
274 use std::hash::{Hash, Hasher};
275
276 let mut hasher1 = DefaultHasher::new();
277 let mut hasher2 = DefaultHasher::new();
278 mix_blend_mode1.hash(&mut hasher1);
279 mix_blend_mode2.hash(&mut hasher2);
280 assert_eq!(hasher1.finish(), hasher2.finish());
281
282 let mut hasher1 = DefaultHasher::new();
283 let mut hasher2 = DefaultHasher::new();
284 background_blend_mode1.hash(&mut hasher1);
285 background_blend_mode2.hash(&mut hasher2);
286 assert_eq!(hasher1.finish(), hasher2.finish());
287 }
288}