1use 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!(MixBlendMode::ColorDodge.to_string(), "mix-blend-color-dodge");
164 assert_eq!(MixBlendMode::ColorBurn.to_string(), "mix-blend-color-burn");
165 assert_eq!(MixBlendMode::HardLight.to_string(), "mix-blend-hard-light");
166 assert_eq!(MixBlendMode::SoftLight.to_string(), "mix-blend-soft-light");
167 assert_eq!(MixBlendMode::Difference.to_string(), "mix-blend-difference");
168 assert_eq!(MixBlendMode::Exclusion.to_string(), "mix-blend-exclusion");
169 assert_eq!(MixBlendMode::Hue.to_string(), "mix-blend-hue");
170 assert_eq!(MixBlendMode::Saturation.to_string(), "mix-blend-saturation");
171 assert_eq!(MixBlendMode::Color.to_string(), "mix-blend-color");
172 assert_eq!(MixBlendMode::Luminosity.to_string(), "mix-blend-luminosity");
173 }
174
175 #[test]
176 fn test_background_blend_mode_display() {
177 assert_eq!(BackgroundBlendMode::Normal.to_string(), "bg-blend-normal");
178 assert_eq!(BackgroundBlendMode::Multiply.to_string(), "bg-blend-multiply");
179 assert_eq!(BackgroundBlendMode::Screen.to_string(), "bg-blend-screen");
180 assert_eq!(BackgroundBlendMode::Overlay.to_string(), "bg-blend-overlay");
181 assert_eq!(BackgroundBlendMode::Darken.to_string(), "bg-blend-darken");
182 assert_eq!(BackgroundBlendMode::Lighten.to_string(), "bg-blend-lighten");
183 assert_eq!(BackgroundBlendMode::ColorDodge.to_string(), "bg-blend-color-dodge");
184 assert_eq!(BackgroundBlendMode::ColorBurn.to_string(), "bg-blend-color-burn");
185 assert_eq!(BackgroundBlendMode::HardLight.to_string(), "bg-blend-hard-light");
186 assert_eq!(BackgroundBlendMode::SoftLight.to_string(), "bg-blend-soft-light");
187 assert_eq!(BackgroundBlendMode::Difference.to_string(), "bg-blend-difference");
188 assert_eq!(BackgroundBlendMode::Exclusion.to_string(), "bg-blend-exclusion");
189 assert_eq!(BackgroundBlendMode::Hue.to_string(), "bg-blend-hue");
190 assert_eq!(BackgroundBlendMode::Saturation.to_string(), "bg-blend-saturation");
191 assert_eq!(BackgroundBlendMode::Color.to_string(), "bg-blend-color");
192 assert_eq!(BackgroundBlendMode::Luminosity.to_string(), "bg-blend-luminosity");
193 }
194
195 #[test]
196 fn test_mix_blend_mode_utilities() {
197 let classes = ClassBuilder::new()
198 .mix_blend_mode(MixBlendMode::Multiply)
199 .build();
200
201 assert!(classes.to_css_classes().contains("mix-blend-multiply"));
202 }
203
204 #[test]
205 fn test_background_blend_mode_utilities() {
206 let classes = ClassBuilder::new()
207 .background_blend_mode(BackgroundBlendMode::Screen)
208 .build();
209
210 assert!(classes.to_css_classes().contains("bg-blend-screen"));
211 }
212
213 #[test]
214 fn test_blend_mode_serialization() {
215 let mix_blend_mode = MixBlendMode::Overlay;
216 let serialized = serde_json::to_string(&mix_blend_mode).unwrap();
217 let deserialized: MixBlendMode = serde_json::from_str(&serialized).unwrap();
218 assert_eq!(mix_blend_mode, deserialized);
219
220 let background_blend_mode = BackgroundBlendMode::Overlay;
221 let serialized = serde_json::to_string(&background_blend_mode).unwrap();
222 let deserialized: BackgroundBlendMode = serde_json::from_str(&serialized).unwrap();
223 assert_eq!(background_blend_mode, deserialized);
224 }
225
226 #[test]
227 fn test_blend_mode_equality_and_hash() {
228 let mix_blend_mode1 = MixBlendMode::Multiply;
229 let mix_blend_mode2 = MixBlendMode::Multiply;
230 let mix_blend_mode3 = MixBlendMode::Screen;
231
232 assert_eq!(mix_blend_mode1, mix_blend_mode2);
233 assert_ne!(mix_blend_mode1, mix_blend_mode3);
234
235 let background_blend_mode1 = BackgroundBlendMode::Multiply;
236 let background_blend_mode2 = BackgroundBlendMode::Multiply;
237 let background_blend_mode3 = BackgroundBlendMode::Screen;
238
239 assert_eq!(background_blend_mode1, background_blend_mode2);
240 assert_ne!(background_blend_mode1, background_blend_mode3);
241
242 use std::collections::hash_map::DefaultHasher;
244 use std::hash::{Hash, Hasher};
245
246 let mut hasher1 = DefaultHasher::new();
247 let mut hasher2 = DefaultHasher::new();
248 mix_blend_mode1.hash(&mut hasher1);
249 mix_blend_mode2.hash(&mut hasher2);
250 assert_eq!(hasher1.finish(), hasher2.finish());
251
252 let mut hasher1 = DefaultHasher::new();
253 let mut hasher2 = DefaultHasher::new();
254 background_blend_mode1.hash(&mut hasher1);
255 background_blend_mode2.hash(&mut hasher2);
256 assert_eq!(hasher1.finish(), hasher2.finish());
257 }
258}