Skip to main content

wonfy_tools/tool/stitcher/
builder.rs

1use image::RgbaImage;
2
3use crate::error::MissingFieldError;
4
5use super::{CheckDirection, ImageStitcher, MatchMode, Order};
6
7#[derive(Debug, Default)]
8pub struct ImageStitcherBuilder {
9    images: Option<Vec<RgbaImage>>,
10    order: Option<Order>,
11    direction: Option<CheckDirection>,
12    window_size: Option<usize>,
13    match_mode: Option<MatchMode>,
14    crop: Option<u32>,
15}
16
17impl ImageStitcherBuilder {
18    pub fn new() -> Self {
19        Default::default()
20    }
21
22    #[must_use]
23    pub fn images<T: Into<Option<Vec<RgbaImage>>>>(self, images: T) -> Self {
24        Self {
25            images: images.into(),
26            ..self
27        }
28    }
29
30    #[must_use]
31    pub fn order<T: Into<Option<Order>>>(self, order: T) -> Self {
32        Self {
33            order: order.into(),
34            ..self
35        }
36    }
37
38    #[must_use]
39    pub fn direction<T: Into<Option<CheckDirection>>>(self, direction: T) -> Self {
40        Self {
41            direction: direction.into(),
42            ..self
43        }
44    }
45
46    #[must_use]
47    pub fn window_size<T: Into<Option<usize>>>(self, window_size: T) -> Self {
48        Self {
49            window_size: window_size.into(),
50            ..self
51        }
52    }
53
54    #[must_use]
55    pub fn match_mode<T: Into<Option<MatchMode>>>(self, match_mode: T) -> Self {
56        Self {
57            match_mode: match_mode.into(),
58            ..self
59        }
60    }
61
62    pub fn crop<T: Into<Option<u32>>>(self, crop: T) -> Self {
63        Self {
64            crop: crop.into(),
65            ..self
66        }
67    }
68
69    pub fn build(self) -> Result<ImageStitcher, MissingFieldError> {
70        macro_rules! builder_field_unwrap {
71            ($field: ident) => {
72                self.$field
73                    .ok_or_else(|| crate::error::MissingFieldError(stringify!($field).into()))?
74            };
75            ($field: ident, $default: literal) => {
76                self.$field.unwrap_or_else(|| $default)
77            };
78        }
79
80        Ok(ImageStitcher::new(
81            builder_field_unwrap!(images),
82            builder_field_unwrap!(order),
83            builder_field_unwrap!(direction),
84            builder_field_unwrap!(window_size),
85            builder_field_unwrap!(match_mode),
86            builder_field_unwrap!(crop, 0),
87        ))
88    }
89}