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
100impl<'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
150fn 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}