Skip to main content

nextcloud_preview/
options.rs

1//! Options and builder for Nextcloud preview requests.
2
3use crate::mode::PreviewMode;
4
5/// Parameters for generating a thumbnail or preview image.
6///
7/// Corresponds to the query parameters accepted by Nextcloud's preview endpoint:
8/// - `x`: Width in pixels
9/// - `y`: Height in pixels
10/// - `a`: Whether to keep aspect ratio (`1` or `0`)
11/// - `mode`: Scaling mode (`"cover"` or `"fill"`)
12#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
13pub struct PreviewOptions {
14    width: Option<u32>,
15    height: Option<u32>,
16    keep_aspect_ratio: Option<bool>,
17    mode: Option<PreviewMode>,
18}
19
20impl PreviewOptions {
21    /// Creates an empty set of preview options.
22    pub const fn new() -> Self {
23        Self {
24            width: None,
25            height: None,
26            keep_aspect_ratio: None,
27            mode: None,
28        }
29    }
30
31    /// Sets the desired preview width in pixels (`x` parameter).
32    #[must_use]
33    pub const fn width(mut self, width: u32) -> Self {
34        self.width = Some(width);
35        self
36    }
37
38    /// Sets the desired preview height in pixels (`y` parameter).
39    #[must_use]
40    pub const fn height(mut self, height: u32) -> Self {
41        self.height = Some(height);
42        self
43    }
44
45    /// Sets both width and height in pixels (`x` and `y` parameters).
46    #[must_use]
47    pub const fn dimensions(mut self, width: u32, height: u32) -> Self {
48        self.width = Some(width);
49        self.height = Some(height);
50        self
51    }
52
53    /// Specifies whether to keep the image aspect ratio (`a` parameter).
54    ///
55    /// When `true`, Nextcloud preserves the aspect ratio (`a=1`).
56    /// When `false`, Nextcloud crops or distorts (`a=0`).
57    #[must_use]
58    pub const fn keep_aspect_ratio(mut self, keep: bool) -> Self {
59        self.keep_aspect_ratio = Some(keep);
60        self
61    }
62
63    /// Sets the scaling mode (`mode` parameter).
64    #[must_use]
65    pub const fn mode(mut self, mode: PreviewMode) -> Self {
66        self.mode = Some(mode);
67        self
68    }
69
70    /// The desired preview width in pixels, if specified.
71    pub const fn width_px(&self) -> Option<u32> {
72        self.width
73    }
74
75    /// The desired preview height in pixels, if specified.
76    pub const fn height_px(&self) -> Option<u32> {
77        self.height
78    }
79
80    /// Whether aspect ratio should be preserved, if specified.
81    pub const fn aspect_ratio(&self) -> Option<bool> {
82        self.keep_aspect_ratio
83    }
84
85    /// The scaling mode, if specified.
86    pub const fn preview_mode(&self) -> Option<PreviewMode> {
87        self.mode
88    }
89}
90
91#[cfg(test)]
92mod tests {
93    use super::PreviewOptions;
94    use crate::mode::PreviewMode;
95
96    #[test]
97    fn default_options_are_empty() {
98        let options = PreviewOptions::new();
99        assert_eq!(options.width_px(), None);
100        assert_eq!(options.height_px(), None);
101        assert_eq!(options.aspect_ratio(), None);
102        assert_eq!(options.preview_mode(), None);
103    }
104
105    #[test]
106    fn builder_sets_all_options() {
107        let options = PreviewOptions::new()
108            .width(256)
109            .height(512)
110            .keep_aspect_ratio(true)
111            .mode(PreviewMode::Cover);
112
113        assert_eq!(options.width_px(), Some(256));
114        assert_eq!(options.height_px(), Some(512));
115        assert_eq!(options.aspect_ratio(), Some(true));
116        assert_eq!(options.preview_mode(), Some(PreviewMode::Cover));
117    }
118
119    #[test]
120    fn dimensions_helper_sets_both_axes() {
121        let options = PreviewOptions::new().dimensions(1024, 768);
122        assert_eq!(options.width_px(), Some(1024));
123        assert_eq!(options.height_px(), Some(768));
124    }
125}