use std::sync::Arc;
use crate::error::Result;
use crate::http::Config;
use crate::types::{
list_query, AddContactSegmentResponse, BatchContactsOptions, BatchContactsResponse,
BatchValidation, Contact, ContactAddress, ContactId, ContactListItem, ContactProperty,
ContactPropertyId, ContactTopicUpdate, CreateContactOptions, CreateContactPropertyOptions,
DeleteContactPropertyResponse, DeleteContactResponse, List, ListOptions,
RemoveContactSegmentResponse, UpdateContactOptions, UpdateContactPropertyOptions,
UpdateContactTopicsResponse,
};
#[derive(Clone)]
pub struct Contacts {
config: Arc<Config>,
pub topics: ContactTopics,
pub segments: ContactSegments,
pub properties: ContactProperties,
}
impl Contacts {
pub(crate) fn new(config: Arc<Config>) -> Self {
Contacts {
topics: ContactTopics(config.clone()),
segments: ContactSegments(config.clone()),
properties: ContactProperties(config.clone()),
config,
}
}
pub async fn create(&self, contact: &CreateContactOptions) -> Result<ContactId> {
self.config.post(&["contacts"], contact).await
}
pub async fn create_batch(
&self,
contacts: &[CreateContactOptions],
options: Option<&BatchContactsOptions>,
) -> Result<BatchContactsResponse> {
let options = options.cloned().unwrap_or_default();
let query: Vec<_> = options
.on_conflict
.map(|c| ("on_conflict", c.as_str().to_string()))
.into_iter()
.collect();
self.config
.post_with(
&["contacts", "batch"],
&query,
contacts,
&[(
"x-batch-validation",
options.batch_validation.map(BatchValidation::as_str),
)],
)
.await
}
pub async fn get(&self, address: impl Into<ContactAddress>) -> Result<Contact> {
let address = address.into();
self.config.get(&["contacts", address.key()], &[]).await
}
pub async fn update(
&self,
address: impl Into<ContactAddress>,
changes: &UpdateContactOptions,
) -> Result<ContactId> {
let address = address.into();
self.config
.patch(&["contacts", address.key()], changes)
.await
}
pub async fn delete(
&self,
address: impl Into<ContactAddress>,
) -> Result<DeleteContactResponse> {
let address = address.into();
self.config.delete(&["contacts", address.key()]).await
}
pub async fn list(&self, options: Option<&ListOptions>) -> Result<List<ContactListItem>> {
self.config.get(&["contacts"], &list_query(options)).await
}
}
#[derive(Clone)]
pub struct ContactTopics(pub(crate) Arc<Config>);
impl ContactTopics {
pub async fn update(
&self,
address: impl Into<ContactAddress>,
topics: &[ContactTopicUpdate],
) -> Result<UpdateContactTopicsResponse> {
let address = address.into();
self.0
.patch(&["contacts", address.key(), "topics"], topics)
.await
}
}
#[derive(Clone)]
pub struct ContactSegments(pub(crate) Arc<Config>);
impl ContactSegments {
pub async fn add(
&self,
address: impl Into<ContactAddress>,
segment_id: &str,
) -> Result<AddContactSegmentResponse> {
let address = address.into();
self.0
.post_empty(&["contacts", address.key(), "segments", segment_id])
.await
}
pub async fn remove(
&self,
address: impl Into<ContactAddress>,
segment_id: &str,
) -> Result<RemoveContactSegmentResponse> {
let address = address.into();
self.0
.delete(&["contacts", address.key(), "segments", segment_id])
.await
}
}
#[derive(Clone)]
pub struct ContactProperties(pub(crate) Arc<Config>);
impl ContactProperties {
pub async fn create(&self, property: &CreateContactPropertyOptions) -> Result<ContactProperty> {
self.0.post(&["contact-properties"], property).await
}
pub async fn get(&self, id: &str) -> Result<ContactProperty> {
self.0.get(&["contact-properties", id], &[]).await
}
pub async fn list(&self, options: Option<&ListOptions>) -> Result<List<ContactProperty>> {
self.0
.get(&["contact-properties"], &list_query(options))
.await
}
pub async fn update(
&self,
id: &str,
changes: &UpdateContactPropertyOptions,
) -> Result<ContactPropertyId> {
self.0.patch(&["contact-properties", id], changes).await
}
pub async fn delete(&self, id: &str) -> Result<DeleteContactPropertyResponse> {
self.0.delete(&["contact-properties", id]).await
}
}