1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use uuid::Uuid;
7
8#[derive(Debug, Clone, Default)]
10pub struct SupabaseConfig {
11 pub url: String,
13 pub key: String,
15 pub service_role_key: Option<String>,
17 pub http_config: HttpConfig,
19 pub auth_config: AuthConfig,
21 pub database_config: DatabaseConfig,
23 pub storage_config: StorageConfig,
25}
26
27#[derive(Debug, Clone)]
29pub struct HttpConfig {
30 pub timeout: u64,
32 pub connect_timeout: u64,
34 pub max_redirects: usize,
36 pub default_headers: HashMap<String, String>,
38}
39
40impl Default for HttpConfig {
41 fn default() -> Self {
42 Self {
43 timeout: 60,
44 connect_timeout: 10,
45 max_redirects: 10,
46 default_headers: HashMap::new(),
47 }
48 }
49}
50
51#[derive(Debug, Clone)]
53pub struct AuthConfig {
54 pub auto_refresh_token: bool,
56 pub refresh_threshold: u64,
58 pub persist_session: bool,
60 pub storage_key: String,
62}
63
64impl Default for AuthConfig {
65 fn default() -> Self {
66 Self {
67 auto_refresh_token: true,
68 refresh_threshold: 300, persist_session: true,
70 storage_key: "supabase.auth.token".to_string(),
71 }
72 }
73}
74
75#[derive(Debug, Clone)]
77pub struct DatabaseConfig {
78 pub schema: String,
80 pub max_retries: u32,
82 pub retry_delay: u64,
84}
85
86impl Default for DatabaseConfig {
87 fn default() -> Self {
88 Self {
89 schema: "public".to_string(),
90 max_retries: 3,
91 retry_delay: 1000,
92 }
93 }
94}
95
96#[derive(Debug, Clone)]
98pub struct StorageConfig {
99 pub default_bucket: Option<String>,
101 pub upload_timeout: u64,
103 pub max_file_size: u64,
105}
106
107impl Default for StorageConfig {
108 fn default() -> Self {
109 Self {
110 default_bucket: None,
111 upload_timeout: 300, max_file_size: 50 * 1024 * 1024, }
114 }
115}
116
117#[derive(Debug, Clone, Serialize, Deserialize)]
119pub struct SupabaseResponse<T> {
120 pub data: Option<T>,
121 pub error: Option<SupabaseError>,
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct SupabaseError {
127 pub message: String,
128 pub details: Option<String>,
129 pub hint: Option<String>,
130 pub code: Option<String>,
131}
132
133#[derive(Debug, Clone, Serialize, Deserialize)]
135pub struct Pagination {
136 pub page: u32,
138 pub per_page: u32,
140 pub total: Option<u64>,
142 pub has_more: Option<bool>,
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
148pub enum FilterOperator {
149 #[serde(rename = "eq")]
150 Equal,
151 #[serde(rename = "neq")]
152 NotEqual,
153 #[serde(rename = "gt")]
154 GreaterThan,
155 #[serde(rename = "gte")]
156 GreaterThanOrEqual,
157 #[serde(rename = "lt")]
158 LessThan,
159 #[serde(rename = "lte")]
160 LessThanOrEqual,
161 #[serde(rename = "like")]
162 Like,
163 #[serde(rename = "ilike")]
164 ILike,
165 #[serde(rename = "is")]
166 Is,
167 #[serde(rename = "in")]
168 In,
169 #[serde(rename = "cs")]
170 Contains,
171 #[serde(rename = "cd")]
172 ContainedBy,
173 #[serde(rename = "sl")]
174 StrictlyLeft,
175 #[serde(rename = "sr")]
176 StrictlyRight,
177 #[serde(rename = "nxr")]
178 NotExtendToRight,
179 #[serde(rename = "nxl")]
180 NotExtendToLeft,
181 #[serde(rename = "adj")]
182 Adjacent,
183}
184
185#[derive(Debug, Clone, Serialize, Deserialize)]
187pub enum OrderDirection {
188 #[serde(rename = "asc")]
189 Ascending,
190 #[serde(rename = "desc")]
191 Descending,
192}
193
194#[derive(Debug, Clone, Copy)]
196pub enum HttpMethod {
197 Get,
198 Post,
199 Put,
200 Patch,
201 Delete,
202 Head,
203 Options,
204}
205
206impl HttpMethod {
207 pub fn as_str(&self) -> &'static str {
208 match self {
209 HttpMethod::Get => "GET",
210 HttpMethod::Post => "POST",
211 HttpMethod::Put => "PUT",
212 HttpMethod::Patch => "PATCH",
213 HttpMethod::Delete => "DELETE",
214 HttpMethod::Head => "HEAD",
215 HttpMethod::Options => "OPTIONS",
216 }
217 }
218}
219
220pub type Timestamp = DateTime<Utc>;
222
223pub type Id = Uuid;
225
226pub type JsonValue = serde_json::Value;
228
229pub type Headers = HashMap<String, String>;
231
232pub type QueryParams = HashMap<String, String>;
234
235#[cfg(test)]
236mod tests {
237 use super::*;
238
239 #[test]
240 fn test_http_config_default() {
241 let config = HttpConfig::default();
242 assert_eq!(config.timeout, 60);
243 assert_eq!(config.connect_timeout, 10);
244 assert_eq!(config.max_redirects, 10);
245 }
246
247 #[test]
248 fn test_auth_config_default() {
249 let config = AuthConfig::default();
250 assert!(config.auto_refresh_token);
251 assert_eq!(config.refresh_threshold, 300);
252 assert!(config.persist_session);
253 }
254
255 #[test]
256 fn test_filter_operator_serialization() {
257 use serde_json;
258 let op = FilterOperator::Equal;
259 let serialized = serde_json::to_string(&op).unwrap();
260 assert_eq!(serialized, "\"eq\"");
261 }
262
263 #[test]
264 fn test_order_direction() {
265 use serde_json;
266 let dir = OrderDirection::Ascending;
267 let serialized = serde_json::to_string(&dir).unwrap();
268 assert_eq!(serialized, "\"asc\"");
269 }
270
271 #[test]
272 fn test_http_method_as_str() {
273 assert_eq!(HttpMethod::Get.as_str(), "GET");
274 assert_eq!(HttpMethod::Post.as_str(), "POST");
275 assert_eq!(HttpMethod::Put.as_str(), "PUT");
276 }
277}