use std::sync::Arc;
use serde::Deserialize;
use crate::client::{execute_with_retry, ClientInner};
use crate::errors::Error;
use crate::types::{ScoreResponse, ScoringRule, ScoringRuleInput};
#[derive(Clone)]
pub struct ScoringResource {
inner: Arc<ClientInner>,
}
impl ScoringResource {
pub(crate) fn new(inner: Arc<ClientInner>) -> Self {
Self { inner }
}
fn rules_url(&self) -> String {
format!("{}/scoring-rules", self.inner.config.base_url)
}
fn rule_url(&self, id: &str) -> String {
format!("{}/scoring-rules/{}", self.inner.config.base_url, id)
}
pub async fn list_rules(&self) -> Result<Vec<ScoringRule>, Error> {
let url = self.rules_url();
let resp = execute_with_retry(&self.inner, || self.inner.http.get(&url)).await?;
#[derive(Deserialize)]
struct RulesResponse {
rules: Vec<ScoringRule>,
}
let body = resp.json::<RulesResponse>().await?;
Ok(body.rules)
}
pub async fn create_rule(&self, input: ScoringRuleInput) -> Result<ScoringRule, Error> {
let url = self.rules_url();
let resp = execute_with_retry(&self.inner, || {
self.inner.http.post(&url).json(&input)
})
.await?;
Ok(resp.json::<ScoringRule>().await?)
}
pub async fn get_rule(&self, id: &str) -> Result<ScoringRule, Error> {
let url = self.rule_url(id);
let resp = execute_with_retry(&self.inner, || self.inner.http.get(&url)).await?;
Ok(resp.json::<ScoringRule>().await?)
}
pub async fn update_rule(&self, id: &str, input: ScoringRuleInput) -> Result<(), Error> {
let url = self.rule_url(id);
execute_with_retry(&self.inner, || {
self.inner.http.put(&url).json(&input)
})
.await?;
Ok(())
}
pub async fn delete_rule(&self, id: &str) -> Result<(), Error> {
let url = self.rule_url(id);
execute_with_retry(&self.inner, || self.inner.http.delete(&url)).await?;
Ok(())
}
pub async fn recalculate(&self, lead_id: &str) -> Result<f64, Error> {
let url = format!("{}/leads/{}/score", self.inner.config.base_url, lead_id);
let resp = execute_with_retry(&self.inner, || self.inner.http.post(&url)).await?;
let body = resp.json::<ScoreResponse>().await?;
Ok(body.score)
}
}