invoance 0.1.0

Official Rust SDK for the Invoance compliance API
Documentation
//! Events resource — `client.events()`.

use std::sync::Arc;

use serde_json::{json, Map, Value};

use crate::error::Error;
use crate::http::{HttpTransport, QueryParams};
use crate::models::events::*;
use crate::validate::assert_sha256_hex;

/// Handle for the `/events` endpoints.
#[derive(Clone)]
pub struct EventsResource {
    t: Arc<HttpTransport>,
}

impl EventsResource {
    pub(crate) fn new(t: Arc<HttpTransport>) -> Self {
        Self { t }
    }

    /// `POST /events` — ingest a compliance event.
    pub async fn ingest(&self, params: IngestEventParams) -> Result<IngestEventResponse, Error> {
        let mut body = Map::new();
        body.insert("event_type".into(), json!(params.event_type));
        body.insert("payload".into(), Value::Object(params.payload));
        if let Some(t) = &params.event_time {
            body.insert("event_time".into(), json!(t));
        }
        if let Some(t) = &params.trace_id {
            body.insert("trace_id".into(), json!(t));
        }
        self.t
            .post(
                "/events",
                Some(&Value::Object(body)),
                params.idempotency_key.as_deref(),
            )
            .await
    }

    /// `GET /events` — paginated event listing.
    pub async fn list(&self, params: ListEventsParams) -> Result<ListEventsResponse, Error> {
        let q: QueryParams = vec![
            ("page", params.page.map(|v| v.to_string())),
            ("limit", params.limit.map(|v| v.to_string())),
            ("date_from", params.date_from),
            ("date_to", params.date_to),
            ("event_type", params.event_type),
        ];
        self.t.get("/events", Some(q)).await
    }

    /// `GET /events/{event_id}` — retrieve a single event.
    pub async fn get(&self, event_id: &str) -> Result<ComplianceEvent, Error> {
        self.t.get(&format!("/events/{event_id}"), None).await
    }

    /// `POST /events/{event_id}/verify` — hash verification.
    ///
    /// Provide **either** `payload_hash` (hex SHA-256) **or** `payload` (raw
    /// JSON — the server canonicalizes and hashes for you). Passing neither
    /// returns a validation error.
    pub async fn verify(
        &self,
        event_id: &str,
        params: VerifyEventParams,
    ) -> Result<VerifyEventResponse, Error> {
        if params.payload_hash.is_none() && params.payload.is_none() {
            return Err(Error::validation(
                "events.verify requires either `payload_hash` or `payload`",
            ));
        }
        let mut body = Map::new();
        if let Some(ph) = &params.payload_hash {
            assert_sha256_hex("payload_hash", ph)?;
            body.insert("payload_hash".into(), json!(ph));
        }
        if let Some(p) = params.payload {
            body.insert("payload".into(), Value::Object(p));
        }
        self.t
            .post(
                &format!("/events/{event_id}/verify"),
                Some(&Value::Object(body)),
                None,
            )
            .await
    }
}