supabase_function_rs/
models.rs

1use std::collections::HashMap;
2use std::fmt;
3use std::fmt::Display;
4use crate::errors::FunctionsError;
5use bytes::Bytes;
6use serde::de::{self, Visitor, MapAccess};
7use serde::{Deserialize, Serialize, Serializer, Deserializer};
8
9#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
10pub enum FunctionRegion {
11    Any,
12    ApNortheast1,
13    ApNortheast2,
14    ApSouth1,
15    ApSoutheast1,
16    ApSoutheast2,
17    CaCentral1,
18    EuCentral1,
19    EuWest1,
20    EuWest2,
21    EuWest3,
22    SaEast1,
23    UsEast1,
24    UsWest1,
25    UsWest2,
26}
27
28impl Display for FunctionRegion {
29    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30        let str = match self {
31            FunctionRegion::Any => "any".to_string(),
32            FunctionRegion::ApNortheast1 => "ap-northeast-1".to_string(),
33            FunctionRegion::ApNortheast2 => "ap-northeast-2".to_string(),
34            FunctionRegion::ApSouth1 => "ap-south-1".to_string(),
35            FunctionRegion::ApSoutheast1 => "ap-southeast-1".to_string(),
36            FunctionRegion::ApSoutheast2 => "ap-southeast-2".to_string(),
37            FunctionRegion::CaCentral1 => "ca-central-1".to_string(),
38            FunctionRegion::EuCentral1 => "eu-central-1".to_string(),
39            FunctionRegion::EuWest1 => "eu-west-1".to_string(),
40            FunctionRegion::EuWest2 => "eu-west-2".to_string(),
41            FunctionRegion::EuWest3 => "eu-west-3".to_string(),
42            FunctionRegion::SaEast1 => "sa-east-1".to_string(),
43            FunctionRegion::UsEast1 => "us-east-1".to_string(),
44            FunctionRegion::UsWest1 => "us-west-1".to_string(),
45            FunctionRegion::UsWest2 => "us-west-2".to_string(),
46        };
47        write!(f, "{}", str)
48    }
49}
50
51#[derive(Debug, Clone, Default)]
52pub struct FunctionInvokeOptions {
53    pub headers: Option<HashMap<String, String>>,
54    pub method: Option<HttpMethod>,
55    pub region: Option<FunctionRegion>,
56    pub body: Option<InvokeBody>,
57}
58
59#[derive(Debug, Clone)]
60pub enum InvokeBody {
61    File(Vec<u8>),
62    Blob(Vec<u8>),
63    ArrayBuffer(Vec<u8>),
64    FormData(HashMap<String, String>),
65    Json(HashMap<String, serde_json::Value>),
66    String(String),
67}
68
69#[derive(Debug, Clone)]
70pub enum HttpMethod {
71    Post,
72    Get,
73    Put,
74    Patch,
75    Delete,
76}
77
78impl HttpMethod {
79    pub(crate) fn as_str(&self) -> &str {
80        match self {
81            HttpMethod::Post => "POST",
82            HttpMethod::Get => "GET",
83            HttpMethod::Put => "PUT",
84            HttpMethod::Patch => "PATCH",
85            HttpMethod::Delete => "DELETE",
86        }
87    }
88}
89
90
91#[derive(Debug, Clone, Serialize)]
92pub enum ResponseData {
93    Json(serde_json::Value),
94    Text(String),
95    #[serde(serialize_with = "serialize_bytes")]
96    Bytes(Bytes),
97    FormData(HashMap<String, String>),
98}
99
100// Implement custom deserialization for ResponseData
101impl<'de> Deserialize<'de> for ResponseData {
102    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
103    where
104        D: Deserializer<'de>,
105    {
106        deserializer.deserialize_any(ResponseDataVisitor)
107    }
108}
109
110struct ResponseDataVisitor;
111
112impl<'de> Visitor<'de> for ResponseDataVisitor {
113    type Value = ResponseData;
114
115    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
116        formatter.write_str("a valid ResponseData variant")
117    }
118
119    fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
120    where
121        V: MapAccess<'de>,
122    {
123        while let Some(key) = map.next_key()? {
124            match key {
125                "Json" => {
126                    let value = map.next_value()?;
127                    return Ok(ResponseData::Json(value));
128                }
129                "Text" => {
130                    let value = map.next_value()?;
131                    return Ok(ResponseData::Text(value));
132                }
133                "Bytes" => {
134                    let value: Vec<u8> = map.next_value()?;
135                    return Ok(ResponseData::Bytes(Bytes::from(value)));
136                }
137                "FormData" => {
138                    let value = map.next_value()?;
139                    return Ok(ResponseData::FormData(value));
140                }
141                _ => return Err(de::Error::unknown_field(key, FIELDS)),
142            }
143        }
144        Err(de::Error::custom("missing fields"))
145    }
146}
147
148const FIELDS: &'static [&'static str] = &["Json", "Text", "Bytes", "FormData"];
149
150// Custom serializer for Bytes
151fn serialize_bytes<S>(bytes: &Bytes, serializer: S) -> Result<S::Ok, S::Error>
152where
153    S: Serializer,
154{
155    serializer.serialize_bytes(bytes)
156}
157
158
159#[derive(Debug)]
160pub enum FunctionsResponse {
161    Success { data: ResponseData },
162    Failure { error: FunctionsError },
163}