dimescheduler 0.1.0

Official Rust client library for the Dime.Scheduler API.
Documentation
use std::marker::PhantomData;

use reqwest::Method;
use serde::de::DeserializeOwned;
use serde::Serialize;

use crate::error::Result;
use crate::transport::Transport;
use crate::types::DimeSchedulerApiResponse;

/// Generic accessor for every import-shaped entity (~33 of them). All write
/// verbs accept one entity or a slice; the API accepts either shape.
///
/// `E` is the request body type (`entities::*`), `D` the DTO `get_all` returns
/// (`types::*Dto`, or `()` for routes the API exposes no GET on).
#[derive(Clone)]
pub struct CrudApi<E, D> {
    transport: Transport,
    route: &'static str,
    _marker: PhantomData<fn() -> (E, D)>,
}

impl<E: Serialize, D: DeserializeOwned> CrudApi<E, D> {
    pub(crate) fn new(transport: Transport, route: &'static str) -> Self {
        Self {
            transport,
            route,
            _marker: PhantomData,
        }
    }

    /// Inserts a single entity.
    pub async fn create(&self, entity: &E) -> Result<DimeSchedulerApiResponse> {
        self.transport
            .send_json(Method::POST, self.route, entity)
            .await
    }

    /// Inserts a batch of entities in one request.
    pub async fn create_many(&self, entities: &[E]) -> Result<DimeSchedulerApiResponse> {
        self.transport
            .send_json(Method::POST, self.route, entities)
            .await
    }

    /// Updates a single existing entity.
    pub async fn update(&self, entity: &E) -> Result<DimeSchedulerApiResponse> {
        self.transport
            .send_json(Method::PUT, self.route, entity)
            .await
    }

    /// Updates a batch of entities in one request.
    pub async fn update_many(&self, entities: &[E]) -> Result<DimeSchedulerApiResponse> {
        self.transport
            .send_json(Method::PUT, self.route, entities)
            .await
    }

    /// Deletes a single entity; the body identifies which one.
    pub async fn delete(&self, entity: &E) -> Result<DimeSchedulerApiResponse> {
        self.transport
            .send_json(Method::DELETE, self.route, entity)
            .await
    }

    /// Deletes a batch of entities in one request.
    pub async fn delete_many(&self, entities: &[E]) -> Result<DimeSchedulerApiResponse> {
        self.transport
            .send_json(Method::DELETE, self.route, entities)
            .await
    }

    /// Lists every record for this entity as the API's read DTO.
    pub async fn get_all(&self) -> Result<Vec<D>> {
        self.transport.get_json(self.route, &[]).await
    }

    /// The API route this accessor targets, e.g. `/category`.
    pub fn route(&self) -> &'static str {
        self.route
    }

    pub(crate) fn transport(&self) -> &Transport {
        &self.transport
    }
}