dregs 1.0.0

The official Rust client for Dregs, which scores the users of your application for fraud and abuse.
Documentation
//! The `client.escalations()` namespace.

use reqwest::Method;
use serde_json::json;

use crate::client::{Client, object_or_null};
use crate::error::Result;
use crate::models::{Escalation, EscalationSeverity, EscalationStatus, EscalationSummary};
use crate::paging::{ItemStream, ListCall, Page, Paging, filter, paging_setters};

/// Read the escalations your escalation rules open, and move them along. Get one from
/// [`Client::escalations`].
#[derive(Debug, Clone, Copy)]
pub struct Escalations<'a> {
    client: &'a Client,
}

impl<'a> Escalations<'a> {
    pub(crate) fn new(client: &'a Client) -> Self {
        Escalations { client }
    }

    /// Returns one page of escalations, newest first.
    ///
    /// Use [`list_all`](Self::list_all) to walk every page.
    pub async fn list(&self, params: ListEscalations) -> Result<Page<Escalation>> {
        params.call().page(self.client).await
    }

    /// Every escalation that matches, fetching pages as it goes. See [`list`](Self::list).
    pub fn list_all(&self, params: ListEscalations) -> ItemStream<Escalation> {
        params.call().walk(self.client)
    }

    /// Returns the escalation with this id.
    ///
    /// Returns an error of kind [`NotFound`](crate::ApiErrorKind::NotFound) when no escalation
    /// has this id.
    pub async fn get(&self, escalation_id: i64) -> Result<Escalation> {
        let payload = self
            .client
            .request(Method::GET, &path(escalation_id), &[], None)
            .await?;

        Ok(Escalation::from_value(object_or_null(payload)))
    }

    /// Moves the escalation to `status`, and returns it.
    ///
    /// Returns an error of kind [`NotFound`](crate::ApiErrorKind::NotFound) when no escalation
    /// has this id.
    pub async fn update(&self, escalation_id: i64, status: EscalationStatus) -> Result<Escalation> {
        let body = json!({ "status": status.as_str() });
        let payload = self
            .client
            .request(Method::PATCH, &path(escalation_id), &[], Some(&body))
            .await?;

        Ok(Escalation::from_value(object_or_null(payload)))
    }

    /// Returns how many escalations are open, acknowledged, and closed.
    pub async fn summary(&self) -> Result<EscalationSummary> {
        let payload = self
            .client
            .request(Method::GET, "/escalations/summary", &[], None)
            .await?;

        Ok(EscalationSummary::from_value(object_or_null(payload)))
    }
}

/// The filters and paging for [`Escalations::list`] and [`Escalations::list_all`].
///
/// Sort on fields such as `"openedAt"` or `"severity"`. A filter left unset is not sent.
#[derive(Debug, Clone, Default)]
pub struct ListEscalations {
    status: Option<EscalationStatus>,
    severity: Option<EscalationSeverity>,
    identity: Option<String>,
    rule: Option<i64>,
    paging: Paging,
}

impl ListEscalations {
    /// Every escalation, from the first page.
    pub fn new() -> Self {
        ListEscalations::default()
    }

    /// Only escalations in this status.
    pub fn status(mut self, status: EscalationStatus) -> Self {
        self.status = Some(status);
        self
    }

    /// Only escalations of this severity.
    pub fn severity(mut self, severity: EscalationSeverity) -> Self {
        self.severity = Some(severity);
        self
    }

    /// Only escalations about this identity.
    pub fn identity(mut self, identity_id: impl Into<String>) -> Self {
        self.identity = Some(identity_id.into());
        self
    }

    /// Only escalations opened by the escalation rule with this id.
    pub fn rule(mut self, rule_id: i64) -> Self {
        self.rule = Some(rule_id);
        self
    }

    paging_setters!();

    fn call(self) -> ListCall<Escalation> {
        let mut filters = Vec::new();

        filter(
            &mut filters,
            "status",
            self.status.map(EscalationStatus::as_str),
        );
        filter(
            &mut filters,
            "severity",
            self.severity.map(EscalationSeverity::as_str),
        );
        filter(&mut filters, "identity", self.identity);
        filter(&mut filters, "rule", self.rule);

        ListCall {
            path: "/escalations",
            filters,
            paging: self.paging,
            parse: Escalation::from_value,
        }
    }
}

fn path(escalation_id: i64) -> String {
    format!("/escalations/{escalation_id}")
}