supabase_storage/model/
options.rs

1use serde::{Serialize, Serializer};
2
3#[derive(Debug, Serialize)]
4pub enum Resize {
5    #[serde(rename = "cover")]
6    Cover,
7    #[serde(rename = "contain")]
8    Contain,
9    #[serde(rename = "fill")]
10    Fill,
11}
12
13impl From<Resize> for &str {
14    fn from(value: Resize) -> Self {
15        match value {
16            Resize::Cover => "cover",
17            Resize::Contain => "contain",
18            Resize::Fill => "fill",
19        }
20    }
21}
22
23#[derive(Debug, Serialize)]
24pub enum Format {
25    #[serde(rename = "origin")]
26    Origin,
27    #[serde(rename = "avif")]
28    Avif,
29}
30
31impl From<Format> for &str {
32    fn from(value: Format) -> Self {
33        match value {
34            Format::Avif => "avif",
35            Format::Origin => "origin",
36        }
37    }
38}
39
40/// * format: Specify the format of the image requested.
41///           When using 'origin' we force the format to be the same as the original image.
42///           When this option is not passed in, images are optimized to modern image formats like Webp.
43/// * height: The height of the image in pixels.
44/// * quality: Set the quality of the returned image.
45///            A number from 20 to 100, with 100 being the highest quality.
46///            Defaults to 80
47/// * resize: The resize mode can be cover, contain or fill.
48///           Defaults to cover.
49///           Cover resizes the image to maintain it's aspect ratio while filling the entire width and height.
50///           Contain resizes the image to maintain it's aspect ratio while fitting the entire image within the width and height. Fill resizes the image to fill the entire width and height. If the object's aspect ratio does not match the width and height, the image will be stretched to fit.
51/// * width: The width of the image in pixels.
52#[derive(Debug, Serialize)]
53pub struct Transform {
54    pub format: Option<Format>,
55    pub height: Option<u32>,
56    pub quality: Option<u32>,
57    pub resize: Option<Resize>,
58    pub width: Option<u32>,
59}
60
61#[derive(Debug, Serialize)]
62pub struct Options {
63    pub download: Option<bool>,
64    pub transform: Option<Transform>,
65}
66
67/// * cache_control: The number of seconds the asset is cached in the browser and in the Supabase CDN.
68///                  This is set in the `Cache-Control: max-age=<seconds>` header. Defaults to 3600 seconds
69/// * content_type: the `Content-Type` header value.
70///                 Should be specified if using a `fileBody` that is neither `Blob` nor `File` nor `FormData`,
71///                 otherwise will default to `text/plain;charset=UTF-8`.
72/// * upsert: When upsert is set to true, the file is overwritten if it exists.
73///           When set to false, an error is thrown if the object already exists.
74///           Defaults to false.
75#[derive(Debug, Serialize)]
76pub struct FileOptions {
77    #[serde(serialize_with = "serialize_cache_control")]
78    #[serde(rename = "cache-control")]
79    pub cache_control: Option<u64>,
80    #[serde(rename = "content-type")]
81    pub content_type: Option<String>,
82    pub upsert: Option<bool>,
83}
84
85fn serialize_cache_control<S>(value: &Option<u64>, serializer: S) -> Result<S::Ok, S::Error>
86where
87    S: Serializer,
88{
89    if let Some(val) = value {
90        serializer.serialize_str(&format!("max-age={}", val))
91    } else {
92        serializer.serialize_none()
93    }
94}
95
96#[cfg(test)]
97mod test {
98    use super::*;
99    #[test]
100    fn test_serialize_file_options() {
101        let options = FileOptions {
102            cache_control: Some(1000),
103            content_type: Some("application/pdf".to_string()),
104            upsert: Some(true),
105        };
106        let serialized = serde_json::to_string(&options).unwrap();
107        assert_eq!(
108            serialized,
109            r#"{"cache-control":"max-age=1000","content-type":"application/pdf","upsert":true}"#
110        );
111    }
112}