dregs 1.0.0

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

use reqwest::Method;

use crate::client::{Client, object_or_null, segment};
use crate::error::Result;
use crate::models::TrackedEvent;
use crate::paging::{ItemStream, ListCall, Page, Paging, filter, paging_setters};

/// Read the events Dregs has recorded. Get one from [`Client::events`]. To record one, use
/// [`Client::track`].
#[derive(Debug, Clone, Copy)]
pub struct Events<'a> {
    client: &'a Client,
}

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

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

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

    /// Returns the event with this id.
    ///
    /// Returns an error of kind [`NotFound`](crate::ApiErrorKind::NotFound) when no event has
    /// this id.
    pub async fn get(&self, event_id: &str) -> Result<TrackedEvent> {
        let path = format!("/events/{}", segment(event_id, "An event id")?);
        let payload = self.client.request(Method::GET, &path, &[], None).await?;

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

/// The filters and paging for [`Events::list`] and [`Events::list_all`].
///
/// Sort on fields such as `"timestamp"` or `"eventName"`. A filter left unset is not sent.
#[derive(Debug, Clone, Default)]
pub struct ListEvents {
    identity: Option<String>,
    group: Option<String>,
    group_type: Option<String>,
    device: Option<String>,
    session: Option<String>,
    term: Option<String>,
    paging: Paging,
}

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

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

    /// Only events sent with the group with this id.
    pub fn group(mut self, group_id: impl Into<String>) -> Self {
        self.group = Some(group_id.into());
        self
    }

    /// Only events sent with a group of this type.
    pub fn group_type(mut self, group_type: impl Into<String>) -> Self {
        self.group_type = Some(group_type.into());
        self
    }

    /// Only events from the device with this fingerprint.
    pub fn device(mut self, fingerprint: impl Into<String>) -> Self {
        self.device = Some(fingerprint.into());
        self
    }

    /// Only events from this browser session.
    pub fn session(mut self, session: impl Into<String>) -> Self {
        self.session = Some(session.into());
        self
    }

    /// Free text matched against event names and data.
    pub fn term(mut self, term: impl Into<String>) -> Self {
        self.term = Some(term.into());
        self
    }

    paging_setters!();

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

        filter(&mut filters, "identity", self.identity);
        filter(&mut filters, "group", self.group);
        filter(&mut filters, "groupType", self.group_type);
        filter(&mut filters, "device", self.device);
        filter(&mut filters, "session", self.session);
        filter(&mut filters, "term", self.term);

        ListCall {
            path: "/events",
            filters,
            paging: self.paging,
            parse: TrackedEvent::from_value,
        }
    }
}