dimescheduler 0.1.0

Official Rust client library for the Dime.Scheduler API.
Documentation
use reqwest::Method;

use crate::error::Result;
use crate::transport::Transport;
use crate::{entities, models, types};

/// Defines a `Clone` accessor struct holding only a `Transport`.
macro_rules! single_api {
    ($name:ident, $doc:literal) => {
        #[doc = $doc]
        #[derive(Clone)]
        pub struct $name {
            transport: Transport,
        }

        impl $name {
            pub(crate) fn new(transport: Transport) -> Self {
                Self { transport }
            }
        }
    };
}

single_api!(ConnectorApi, "Register webhook-style connectors.");
single_api!(GeocodeApi, "Convert addresses to geographic coordinates.");
single_api!(
    ImportApi,
    "Bulk imports: stored-procedure data records and setup payloads."
);
single_api!(
    MessageApi,
    "Send a transient message to a user, or to every user in the tenant."
);
single_api!(OptimizationApi, "Run the optimisation solvers.");
single_api!(RecommendationApi, "Resource recommendation engine.");
single_api!(
    RecurringAppointmentApi,
    "Create or delete a recurring appointment series."
);
single_api!(UserApi, "API user administration.");

impl ConnectorApi {
    pub async fn create(&self, request: &types::NewConnectorRequest) -> Result<()> {
        self.transport
            .send_empty(Method::POST, "/connector", request)
            .await
    }
}

impl GeocodeApi {
    /// Geocodes a structured address. The response shape is not described by
    /// the spec, so it is returned as JSON.
    pub async fn geocode(&self, address: &types::Address) -> Result<serde_json::Value> {
        self.transport
            .send_json(Method::POST, "/geocode", address)
            .await
    }

    /// Geocodes a free-text address within a country code.
    pub async fn geocode_text(&self, address: &str, country: &str) -> Result<serde_json::Value> {
        self.transport
            .get_json(
                "/geocode",
                &[
                    ("address", address.to_string()),
                    ("country", country.to_string()),
                ],
            )
            .await
    }
}

impl ImportApi {
    /// Pushes stored-procedure data records.
    pub async fn run(&self, data: &[models::StoredProcedureData]) -> Result<()> {
        self.transport
            .send_empty(Method::POST, "/import", data)
            .await
    }

    /// Queues a setup payload (profiles and layouts) for background import.
    pub async fn setup(&self, payload: &types::SetupImportPayloadDto) -> Result<()> {
        self.transport
            .send_empty(Method::POST, "/import/setup", payload)
            .await
    }
}

impl MessageApi {
    pub async fn send(&self, message: &entities::Message) -> Result<()> {
        self.transport
            .send_empty(Method::POST, "/message", message)
            .await
    }
}

impl OptimizationApi {
    pub async fn field_service(
        &self,
        request: &types::FieldServiceOptimizationRequest,
    ) -> Result<()> {
        self.transport
            .send_empty(Method::POST, "/optimization/fieldService", request)
            .await
    }

    pub async fn professional_services(
        &self,
        request: &types::ProfessionalServicesOptimizationRequest,
    ) -> Result<()> {
        self.transport
            .send_empty(Method::POST, "/optimization/professionalServices", request)
            .await
    }

    pub async fn daily_route(&self, request: &types::OptimizeDailyRouteRequest) -> Result<()> {
        self.transport
            .send_empty(Method::POST, "/optimization/dailyRoute", request)
            .await
    }
}

impl RecommendationApi {
    /// Recommended resources or slots for a request. The response shape is
    /// not described by the spec, so it is returned as JSON.
    pub async fn get(&self, request: &types::RecommendationRequest) -> Result<serde_json::Value> {
        self.transport
            .send_json(Method::POST, "/recommendation", request)
            .await
    }

    /// The scorer keys that can be weighted in a recommendation request.
    pub async fn scorers(&self) -> Result<Vec<serde_json::Value>> {
        self.transport
            .get_json("/recommendation/scorers", &[])
            .await
    }
}

impl RecurringAppointmentApi {
    /// Creates a master appointment plus every occurrence of the pattern.
    pub async fn create(&self, request: &types::RecurringAppointmentRequest) -> Result<()> {
        self.transport
            .send_empty(Method::POST, "/appointmentRecurring", request)
            .await
    }

    /// Deletes an entire series given any appointment id in it.
    pub async fn delete(&self, request: &types::DeleteRecurringAppointmentRequest) -> Result<()> {
        self.transport
            .send_empty(Method::DELETE, "/appointmentRecurring", request)
            .await
    }
}

impl UserApi {
    pub async fn create(&self, user: &types::ApiUser) -> Result<()> {
        self.transport.send_empty(Method::POST, "/user", user).await
    }
}