use percent_encoding::{AsciiSet, NON_ALPHANUMERIC, utf8_percent_encode};
use reqwest::Method;
use serde_json::Value;
use crate::client::Client;
use crate::error::{Error, Result};
use crate::models::{Analysis, Identity, Scores};
const PATH_SEGMENT: &AsciiSet = &NON_ALPHANUMERIC
.remove(b'-')
.remove(b'.')
.remove(b'_')
.remove(b'~');
#[derive(Debug, Clone, Copy)]
pub struct Identities<'a> {
client: &'a Client,
}
impl<'a> Identities<'a> {
pub(crate) fn new(client: &'a Client) -> Self {
Identities { client }
}
pub async fn get(&self, identity_id: &str) -> Result<Identity> {
let payload = self
.client
.request(Method::GET, &path(identity_id, "")?, None)
.await?;
Ok(Identity::from_value(object_or_null(payload)))
}
pub async fn scores(&self, identity_id: &str) -> Result<Scores> {
let payload = self
.client
.request(Method::GET, &path(identity_id, "/scores")?, None)
.await?;
Ok(Scores::from_value(&payload.unwrap_or(Value::Null)))
}
pub async fn analysis(&self, identity_id: &str) -> Result<Analysis> {
let payload = self
.client
.request(Method::GET, &path(identity_id, "/analysis")?, None)
.await?;
Ok(Analysis::from_value(object_or_null(payload)))
}
pub async fn analyze(&self, identity_id: &str) -> Result<()> {
self.client
.request(Method::POST, &path(identity_id, "/actions/analyze")?, None)
.await?;
Ok(())
}
}
fn path(identity_id: &str, suffix: &str) -> Result<String> {
if identity_id.is_empty() {
return Err(Error::InvalidArgument("An identity id is required.".into()));
}
Ok(format!(
"/identities/{}{suffix}",
utf8_percent_encode(identity_id, PATH_SEGMENT)
))
}
fn object_or_null(payload: Option<Value>) -> Value {
payload.filter(Value::is_object).unwrap_or(Value::Null)
}