use crate::error::{MktError, Result};
use crate::models::{
Ad, AdSet, Audience, AudienceId, AudienceUpdateResult, AudienceUser, Campaign, CampaignFilters,
CampaignId, CreateAdSetInput, CreateAudienceInput, CreateCampaignInput, CreateCreativeInput,
CreateDarkPostInput, Creative, HttpMethod, InsightsQuery, InsightsReport, MediaAsset,
Paginated, Post, PostId, PromotePostInput, ProviderHealth, PublishPostInput,
UpdateCampaignInput, UploadImageInput, UploadVideoInput,
};
#[derive(Debug, Clone)]
#[allow(clippy::struct_excessive_bools)] pub struct ProviderCapabilities {
pub campaigns: bool,
pub adsets: bool,
pub ads: bool,
pub creatives: bool,
pub audiences: bool,
pub insights: bool,
pub organic_posts: bool,
pub dark_posts: bool,
pub video_upload: bool,
pub image_upload: bool,
pub workflow_templates: bool,
}
pub trait MarketingProvider: Send + Sync {
fn name(&self) -> &'static str;
fn display_name(&self) -> &'static str;
fn capabilities(&self) -> ProviderCapabilities;
fn list_campaigns(
&self,
filters: &CampaignFilters,
) -> impl std::future::Future<Output = Result<Paginated<Campaign>>> + Send;
fn get_campaign(
&self,
id: &CampaignId,
) -> impl std::future::Future<Output = Result<Campaign>> + Send;
fn create_campaign(
&self,
input: &CreateCampaignInput,
) -> impl std::future::Future<Output = Result<Campaign>> + Send;
fn update_campaign(
&self,
id: &CampaignId,
input: &UpdateCampaignInput,
) -> impl std::future::Future<Output = Result<Campaign>> + Send;
fn delete_campaign(
&self,
id: &CampaignId,
) -> impl std::future::Future<Output = Result<()>> + Send;
fn list_adsets(
&self,
_campaign_id: &CampaignId,
) -> impl std::future::Future<Output = Result<Paginated<AdSet>>> + Send {
async { Err(MktError::not_supported(self.name(), "adsets")) }
}
fn create_adset(
&self,
_input: &CreateAdSetInput,
) -> impl std::future::Future<Output = Result<AdSet>> + Send {
async { Err(MktError::not_supported(self.name(), "adsets")) }
}
fn create_creative(
&self,
_input: &CreateCreativeInput,
) -> impl std::future::Future<Output = Result<Creative>> + Send {
async { Err(MktError::not_supported(self.name(), "creatives")) }
}
fn create_dark_post(
&self,
_input: &CreateDarkPostInput,
) -> impl std::future::Future<Output = Result<Creative>> + Send {
async { Err(MktError::not_supported(self.name(), "dark_posts")) }
}
fn list_audiences(&self) -> impl std::future::Future<Output = Result<Vec<Audience>>> + Send {
async { Err(MktError::not_supported(self.name(), "audiences")) }
}
fn create_audience(
&self,
_input: &CreateAudienceInput,
) -> impl std::future::Future<Output = Result<Audience>> + Send {
async { Err(MktError::not_supported(self.name(), "audiences")) }
}
fn add_users_to_audience(
&self,
_id: &AudienceId,
_users: &[AudienceUser],
) -> impl std::future::Future<Output = Result<AudienceUpdateResult>> + Send {
async { Err(MktError::not_supported(self.name(), "audience_users")) }
}
fn get_insights(
&self,
_query: &InsightsQuery,
) -> impl std::future::Future<Output = Result<InsightsReport>> + Send {
async { Err(MktError::not_supported(self.name(), "insights")) }
}
fn publish_post(
&self,
_input: &PublishPostInput,
) -> impl std::future::Future<Output = Result<Post>> + Send {
async { Err(MktError::not_supported(self.name(), "organic_posts")) }
}
fn promote_post(
&self,
_post_id: &PostId,
_input: &PromotePostInput,
) -> impl std::future::Future<Output = Result<Ad>> + Send {
async { Err(MktError::not_supported(self.name(), "promote_post")) }
}
fn upload_image(
&self,
_input: &UploadImageInput,
) -> impl std::future::Future<Output = Result<MediaAsset>> + Send {
async { Err(MktError::not_supported(self.name(), "image_upload")) }
}
fn upload_video(
&self,
_input: &UploadVideoInput,
) -> impl std::future::Future<Output = Result<MediaAsset>> + Send {
async { Err(MktError::not_supported(self.name(), "video_upload")) }
}
fn raw_request(
&self,
_method: HttpMethod,
_path: &str,
_params: &serde_json::Value,
) -> impl std::future::Future<Output = Result<serde_json::Value>> + Send {
async { Err(MktError::not_supported(self.name(), "raw_request")) }
}
fn health_check(&self) -> impl std::future::Future<Output = Result<ProviderHealth>> + Send {
async { Err(MktError::not_supported(self.name(), "health_check")) }
}
}