use serde::{Deserialize, Serialize, de::DeserializeOwned};
use crate::{calendar::config::CalendarConfig, event::Event};
pub trait ProviderCommand: Serialize {
type Response: DeserializeOwned;
fn command() -> Command;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Command {
Connect,
ListCalendars,
ListEvents,
CreateEvent,
UpdateEvent,
DeleteEvent,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum ConnectStepKind {
OAuthRedirect,
HostedOAuth,
Credentials,
NeedsSetup,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct OAuthData {
pub authorization_url: String,
pub state: String,
pub scopes: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HostedOAuthData {
pub url: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CredentialsData {
pub fields: Vec<CredentialField>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SetupData {
pub instructions: String,
pub fields: Vec<CredentialField>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CredentialField {
pub id: String,
pub label: String,
pub field_type: FieldType,
#[serde(default)]
pub required: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub help: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum FieldType {
Text,
Password,
Url,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Request {
pub command: Command,
#[serde(default)]
pub params: serde_json::Value,
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(tag = "status", rename_all = "snake_case")]
pub enum Response<T> {
Success { data: T },
Error { error: String },
}
impl<T: Serialize> Response<T> {
pub fn success(data: T) -> String {
serde_json::to_string(&Response::Success { data }).unwrap()
}
}
impl Response<()> {
pub fn error(msg: &str) -> String {
serde_json::to_string(&Response::<()>::Error {
error: msg.to_string(),
})
.unwrap()
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Connect {
#[serde(default)]
pub options: serde_json::Map<String, serde_json::Value>,
#[serde(default)]
pub data: serde_json::Map<String, serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "status", rename_all = "snake_case")]
pub enum ConnectResponse {
NeedsInput {
step: ConnectStepKind,
#[serde(flatten)]
data: serde_json::Value,
},
Done { account_identifier: String },
}
impl ProviderCommand for Connect {
type Response = ConnectResponse;
fn command() -> Command {
Command::Connect
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ListCalendars {
pub account_identifier: String,
}
impl ProviderCommand for ListCalendars {
type Response = Vec<CalendarConfig>;
fn command() -> Command {
Command::ListCalendars
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ListEvents {
#[serde(flatten)]
pub remote_config: serde_json::Map<String, serde_json::Value>,
pub from: String,
pub to: String,
}
impl ProviderCommand for ListEvents {
type Response = Vec<Event>;
fn command() -> Command {
Command::ListEvents
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CreateEvent {
#[serde(flatten)]
pub remote_config: serde_json::Map<String, serde_json::Value>,
pub event: Event,
}
impl ProviderCommand for CreateEvent {
type Response = Event;
fn command() -> Command {
Command::CreateEvent
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct UpdateEvent {
#[serde(flatten)]
pub remote_config: serde_json::Map<String, serde_json::Value>,
pub event: Event,
}
impl ProviderCommand for UpdateEvent {
type Response = Event;
fn command() -> Command {
Command::UpdateEvent
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct DeleteEvent {
#[serde(flatten)]
pub remote_config: serde_json::Map<String, serde_json::Value>,
pub event: Event,
}
impl ProviderCommand for DeleteEvent {
type Response = ();
fn command() -> Command {
Command::DeleteEvent
}
}