stew_lib/operations/
mod.rs

1use arrayvec::ArrayVec;
2
3#[cfg(test)]
4mod mod_test_includes;
5
6pub(crate) mod transformations;
7
8#[derive(Debug, PartialEq, Clone)]
9pub enum Operation {
10    Blur(f32),
11    Brighten(i32),
12    Contrast(f32),
13    Crop(u32, u32, u32, u32),
14    Filter3x3(ArrayVec<[f32; 9]>),
15    FlipHorizontal,
16    FlipVertical,
17    GrayScale,
18    HueRotate(i32),
19    Invert,
20    Resize(u32, u32),
21    Rotate90,
22    Rotate180,
23    Rotate270,
24    Unsharpen(f32, i32),
25}
26
27pub enum OpArg {
28    Empty,
29    FloatingPoint(f32),
30    Integer(i32),
31    UnsignedIntegerTuple2(u32, u32),
32    UnsignedIntegerTuple4(u32, u32, u32, u32),
33    FloatingPointArrayVec9(ArrayVec<[f32; 9]>),
34    FloatingPointIntegerTuple2(f32, i32),
35}
36
37pub fn operation_by_name(name: &str, value: OpArg) -> Result<Operation, String> {
38    match (name, value) {
39        ("blur", OpArg::FloatingPoint(v)) => Ok(Operation::Blur(v)),
40        ("brighten", OpArg::Integer(v)) => Ok(Operation::Brighten(v)),
41        ("contrast", OpArg::FloatingPoint(v)) => Ok(Operation::Contrast(v)),
42        ("crop", OpArg::UnsignedIntegerTuple4(u0, u1, u2, u3)) => {
43            Ok(Operation::Crop(u0, u1, u2, u3))
44        }
45        ("filter3x3", OpArg::FloatingPointArrayVec9(v)) => Ok(Operation::Filter3x3(v)),
46        ("fliph", OpArg::Empty) => Ok(Operation::FlipHorizontal),
47        ("flipv", OpArg::Empty) => Ok(Operation::FlipVertical),
48        ("grayscale", OpArg::Empty) => Ok(Operation::GrayScale),
49        ("huerotate", OpArg::Integer(v)) => Ok(Operation::HueRotate(v)),
50        ("invert", OpArg::Empty) => Ok(Operation::Invert),
51        ("resize", OpArg::UnsignedIntegerTuple2(u0, u1)) => Ok(Operation::Resize(u0, u1)),
52        ("rotate90", OpArg::Empty) => Ok(Operation::Rotate90),
53        ("rotate180", OpArg::Empty) => Ok(Operation::Rotate180),
54        ("rotate270", OpArg::Empty) => Ok(Operation::Rotate270),
55        ("unsharpen", OpArg::FloatingPointIntegerTuple2(f, i)) => Ok(Operation::Unsharpen(f, i)),
56        _ => Err("No suitable operation was found.".to_string()),
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    // blur
65    // ----------
66
67    #[test]
68    fn blur_ok() {
69        let actual = operation_by_name("blur", OpArg::FloatingPoint(1.5));
70
71        assert_eq!(actual, Ok(Operation::Blur(1.5)));
72    }
73
74    #[test]
75    fn blur_name_err() {
76        let actual = operation_by_name("blur'", OpArg::FloatingPoint(1.5));
77
78        assert_ne!(actual, Ok(Operation::Blur(1.5)));
79    }
80
81    #[test]
82    fn blur_arg_err() {
83        let actual = operation_by_name("blur", OpArg::Empty);
84
85        assert_ne!(actual, Ok(Operation::Blur(1.5)));
86    }
87
88    // brighten
89    // ----------
90
91    #[test]
92    fn brighten_ok() {
93        let actual = operation_by_name("brighten", OpArg::Integer(-25));
94
95        assert_eq!(actual, Ok(Operation::Brighten(-25)));
96    }
97
98    // contrast
99    // ----------
100
101    #[test]
102    fn contrast_ok() {
103        let actual = operation_by_name("contrast", OpArg::FloatingPoint(1.5));
104
105        assert_eq!(actual, Ok(Operation::Contrast(1.5)));
106    }
107
108    // crop
109    // ----------
110
111    #[test]
112    fn crop_ok() {
113        let actual = operation_by_name("crop", OpArg::UnsignedIntegerTuple4(0, 1, 2, 3));
114
115        assert_eq!(actual, Ok(Operation::Crop(0, 1, 2, 3)));
116    }
117
118    // filter3x3
119    // ----------
120
121    #[test]
122    fn filter3x3_ok() {
123        let array = ArrayVec::<[f32; 9]>::default();
124
125        let actual = operation_by_name("filter3x3", OpArg::FloatingPointArrayVec9(array));
126
127        assert_eq!(
128            actual,
129            Ok(Operation::Filter3x3(ArrayVec::<[f32; 9]>::default()))
130        );
131    }
132
133    // fliph
134    // ----------
135
136    #[test]
137    fn fliph_ok() {
138        let actual = operation_by_name("fliph", OpArg::Empty);
139
140        assert_eq!(actual, Ok(Operation::FlipHorizontal));
141    }
142
143    // flipv
144    // ----------
145
146    #[test]
147    fn flipv_ok() {
148        let actual = operation_by_name("flipv", OpArg::Empty);
149
150        assert_eq!(actual, Ok(Operation::FlipVertical));
151    }
152
153    // grayscale
154    // ----------
155
156    #[test]
157    fn grayscale_ok() {
158        let actual = operation_by_name("grayscale", OpArg::Empty);
159
160        assert_eq!(actual, Ok(Operation::GrayScale));
161    }
162
163    // huerotate
164    // ----------
165
166    #[test]
167    fn huerotate_ok() {
168        let actual = operation_by_name("huerotate", OpArg::Integer(-399));
169
170        assert_eq!(actual, Ok(Operation::HueRotate(-399)));
171    }
172
173    // invert
174    // ----------
175
176    #[test]
177    fn invert_ok() {
178        let actual = operation_by_name("invert", OpArg::Empty);
179
180        assert_eq!(actual, Ok(Operation::Invert));
181    }
182
183    // resize
184    // ----------
185
186    #[test]
187    fn resize_ok() {
188        let actual = operation_by_name("resize", OpArg::UnsignedIntegerTuple2(80, 40));
189
190        assert_eq!(actual, Ok(Operation::Resize(80, 40)));
191    }
192
193    // rotate90
194    // ----------
195
196    #[test]
197    fn rotate90_ok() {
198        let actual = operation_by_name("rotate90", OpArg::Empty);
199
200        assert_eq!(actual, Ok(Operation::Rotate90));
201    }
202
203    // rotate180
204    // ----------
205
206    #[test]
207    fn rotate180_ok() {
208        let actual = operation_by_name("rotate180", OpArg::Empty);
209
210        assert_eq!(actual, Ok(Operation::Rotate180));
211    }
212
213    // rotate270
214    // ----------
215
216    #[test]
217    fn rotate270_ok() {
218        let actual = operation_by_name("rotate270", OpArg::Empty);
219
220        assert_eq!(actual, Ok(Operation::Rotate270));
221    }
222
223    // unsharpen
224    // ----------
225
226    #[test]
227    fn unsharpen_ok() {
228        let actual = operation_by_name("unsharpen", OpArg::FloatingPointIntegerTuple2(1.5, 3));
229
230        assert_eq!(actual, Ok(Operation::Unsharpen(1.5, 3)));
231    }
232}