use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use uuid::Uuid;
#[derive(Debug, Clone, Default)]
pub struct SupabaseConfig {
pub url: String,
pub key: String,
pub service_role_key: Option<String>,
pub http_config: HttpConfig,
pub auth_config: AuthConfig,
pub database_config: DatabaseConfig,
pub storage_config: StorageConfig,
}
#[derive(Debug, Clone)]
pub struct HttpConfig {
pub timeout: u64,
pub connect_timeout: u64,
pub max_redirects: usize,
pub default_headers: HashMap<String, String>,
}
impl Default for HttpConfig {
fn default() -> Self {
Self {
timeout: 60,
connect_timeout: 10,
max_redirects: 10,
default_headers: HashMap::new(),
}
}
}
#[derive(Debug, Clone)]
pub struct AuthConfig {
pub auto_refresh_token: bool,
pub refresh_threshold: u64,
pub persist_session: bool,
pub storage_key: String,
}
impl Default for AuthConfig {
fn default() -> Self {
Self {
auto_refresh_token: true,
refresh_threshold: 300, persist_session: true,
storage_key: "supabase.auth.token".to_string(),
}
}
}
#[derive(Debug, Clone)]
pub struct DatabaseConfig {
pub schema: String,
pub max_retries: u32,
pub retry_delay: u64,
}
impl Default for DatabaseConfig {
fn default() -> Self {
Self {
schema: "public".to_string(),
max_retries: 3,
retry_delay: 1000,
}
}
}
#[derive(Debug, Clone)]
pub struct StorageConfig {
pub default_bucket: Option<String>,
pub upload_timeout: u64,
pub max_file_size: u64,
}
impl Default for StorageConfig {
fn default() -> Self {
Self {
default_bucket: None,
upload_timeout: 300, max_file_size: 50 * 1024 * 1024, }
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SupabaseResponse<T> {
pub data: Option<T>,
pub error: Option<SupabaseError>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SupabaseError {
pub message: String,
pub details: Option<String>,
pub hint: Option<String>,
pub code: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Pagination {
pub page: u32,
pub per_page: u32,
pub total: Option<u64>,
pub has_more: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum FilterOperator {
#[serde(rename = "eq")]
Equal,
#[serde(rename = "neq")]
NotEqual,
#[serde(rename = "gt")]
GreaterThan,
#[serde(rename = "gte")]
GreaterThanOrEqual,
#[serde(rename = "lt")]
LessThan,
#[serde(rename = "lte")]
LessThanOrEqual,
#[serde(rename = "like")]
Like,
#[serde(rename = "ilike")]
ILike,
#[serde(rename = "is")]
Is,
#[serde(rename = "in")]
In,
#[serde(rename = "cs")]
Contains,
#[serde(rename = "cd")]
ContainedBy,
#[serde(rename = "sl")]
StrictlyLeft,
#[serde(rename = "sr")]
StrictlyRight,
#[serde(rename = "nxr")]
NotExtendToRight,
#[serde(rename = "nxl")]
NotExtendToLeft,
#[serde(rename = "adj")]
Adjacent,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum OrderDirection {
#[serde(rename = "asc")]
Ascending,
#[serde(rename = "desc")]
Descending,
}
#[derive(Debug, Clone, Copy)]
pub enum HttpMethod {
Get,
Post,
Put,
Patch,
Delete,
Head,
Options,
}
impl HttpMethod {
pub fn as_str(&self) -> &'static str {
match self {
HttpMethod::Get => "GET",
HttpMethod::Post => "POST",
HttpMethod::Put => "PUT",
HttpMethod::Patch => "PATCH",
HttpMethod::Delete => "DELETE",
HttpMethod::Head => "HEAD",
HttpMethod::Options => "OPTIONS",
}
}
}
pub type Timestamp = DateTime<Utc>;
pub type Id = Uuid;
pub type JsonValue = serde_json::Value;
pub type Headers = HashMap<String, String>;
pub type QueryParams = HashMap<String, String>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_http_config_default() {
let config = HttpConfig::default();
assert_eq!(config.timeout, 60);
assert_eq!(config.connect_timeout, 10);
assert_eq!(config.max_redirects, 10);
}
#[test]
fn test_auth_config_default() {
let config = AuthConfig::default();
assert!(config.auto_refresh_token);
assert_eq!(config.refresh_threshold, 300);
assert!(config.persist_session);
}
#[test]
fn test_filter_operator_serialization() {
use serde_json;
let op = FilterOperator::Equal;
let serialized = serde_json::to_string(&op).unwrap();
assert_eq!(serialized, "\"eq\"");
}
#[test]
fn test_order_direction() {
use serde_json;
let dir = OrderDirection::Ascending;
let serialized = serde_json::to_string(&dir).unwrap();
assert_eq!(serialized, "\"asc\"");
}
#[test]
fn test_http_method_as_str() {
assert_eq!(HttpMethod::Get.as_str(), "GET");
assert_eq!(HttpMethod::Post.as_str(), "POST");
assert_eq!(HttpMethod::Put.as_str(), "PUT");
}
}