keplars 2.1.0

Official Rust SDK for Keplars Email API
Documentation
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use serde_json::Value;

pub struct KeplarsConfig {
    pub api_key: String,
    pub base_url: String,
    pub timeout: std::time::Duration,
    pub max_retries: u32,
    pub retry_delay: std::time::Duration,
}

impl Default for KeplarsConfig {
    fn default() -> Self {
        Self {
            api_key: String::new(),
            base_url: "https://api.keplars.com".to_string(),
            timeout: std::time::Duration::from_secs(30),
            max_retries: 3,
            retry_delay: std::time::Duration::from_secs(1),
        }
    }
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum ToRecipient {
    Email(String),
    Emails(Vec<String>),
}

#[derive(Debug, Clone, Serialize)]
pub struct SendEmailRequest {
    pub to: ToRecipient,
    pub from: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub from_name: Option<String>,
    pub subject: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub body: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub is_html: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cc: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub bcc: Option<Vec<String>>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub template_id: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub params: Option<HashMap<String, Value>>,
}

#[derive(Debug, Clone, Serialize)]
pub struct ScheduleEmailRequest {
    #[serde(flatten)]
    pub email: SendEmailRequest,
    pub scheduled_for: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub timezone: Option<String>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct EmailMetadata {
    pub priority: Option<String>,
    pub estimated_delivery: Option<String>,
    pub recipients_count: Option<u32>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct SendEmailResponse {
    pub id: String,
    pub object: Option<String>,
    pub status: Option<String>,
    pub from: Option<String>,
    pub to: Option<Vec<String>>,
    pub subject: Option<String>,
    pub created_at: Option<String>,
    pub metadata: Option<EmailMetadata>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Contact {
    pub id: String,
    pub email: String,
    pub name: Option<String>,
    pub audience_id: Option<String>,
    pub created_at: String,
    pub updated_at: Option<String>,
}

#[derive(Debug, Clone, Serialize)]
pub struct AddContactRequest {
    pub email: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub audience_id: Option<String>,
}

#[derive(Debug, Clone, Serialize)]
pub struct UpdateContactRequest {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub audience_id: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Audience {
    pub id: String,
    pub name: String,
    pub description: Option<String>,
    pub created_at: String,
    pub updated_at: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Automation {
    pub id: String,
    pub name: String,
    pub status: String,
    pub created_at: String,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DomainListItem {
    pub id: String,
    pub domain: String,
    pub verified: bool,
    pub created_at: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct ApiResponse<T> {
    pub success: bool,
    pub message: String,
    pub data: T,
}

#[derive(Debug, Clone, Deserialize)]
pub struct ApiDataResponse<T> {
    pub success: bool,
    pub data: T,
}

#[derive(Debug, Clone, Deserialize)]
pub struct ApiListResponse<T> {
    pub success: bool,
    pub data: Vec<T>,
    pub meta: HashMap<String, Value>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct ApiMessageResponse {
    pub success: bool,
    pub message: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct RateLimitInfo {
    pub limit: u32,
    pub remaining: u32,
    pub reset: u64,
}

#[derive(Debug, Clone, Deserialize)]
pub struct CreateDomainData {
    pub domain_id: String,
    pub domain: String,
    pub dns_records: Vec<HashMap<String, Value>>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct DomainStatusData {
    pub domain_id: String,
    pub domain: String,
    pub verified: bool,
    pub dns_records: Vec<HashMap<String, Value>>,
}

#[derive(Debug, Clone, Deserialize)]
pub struct DomainVerificationData {
    pub verified: bool,
    pub domain: String,
}

#[derive(Debug, Clone, Deserialize)]
pub struct DomainApiKeyData {
    pub api_key: String,
    pub domain_id: String,
}

#[derive(Debug, Clone, Serialize)]
pub struct CreateDomainApiKeyRequest {
    pub domain_id: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
}