lightspeed_api 0.1.4

A Rust crate for the Lightspeed eCommerce (C-Series) API
Documentation
use reqwest::Client;
use serde::{Deserialize, Serialize};
use std::error::Error;
use crate::error::LightspeedApiError;

pub struct LightspeedClient {
    client: Client,
    api_key: String,
    api_secret: String,
    api_language: String,
    api_server: String
}

impl LightspeedClient {
    pub fn new(api_server: &str, api_key: &str, api_secret: &str, api_language: &str) -> Self {
        Self {
            client: Client::new(),
            api_key: api_key.to_string(),
            api_secret: api_secret.to_string(),
            api_language: api_language.to_string(),
            api_server: api_server.to_string(),
        }
    }

    fn get_url(&self, resource_url: &str) -> String {
        let api_host = match self.api_server.as_str() {
            "live" => "https://api.webshopapp.com/",
            "local" => "https://api.webshopapp.dev/",
            "eu1" => "https://api.webshopapp.com/",
            "us1" => "https://api.shoplightspeed.com/",
            _ => panic!("Invalid API server"),
        };

        let resource_url = if resource_url.ends_with(".json") {
            resource_url.to_string()
        } else {
            format!("{}.json", resource_url)
        };

        format!(
            "{}{}{}{}",
            api_host, self.api_language, "/", resource_url
        )
    }

    pub async fn create<T: Serialize, R: for<'de> Deserialize<'de>>(
        &self,
        url: &str,
        payload: &T,
    ) -> Result<R, Box<dyn Error>> {
        let url = self.get_url(url);
        let response = self
            .client
            .post(url)
            .basic_auth(&self.api_key, Some(&self.api_secret))
            .json(payload)
            .send()
            .await?;

        self.handle_response(response).await
    }

    pub async fn read<R: for<'de> Deserialize<'de>>(
        &self,
        url: &str,
        params: Option<Vec<(&str, &str)>>,
    ) -> Result<R, Box<dyn Error>> {
        let url = self.get_url(url);
        let mut request = self
            .client
            .get(url)
            .basic_auth(&self.api_key, Some(&self.api_secret));

        if let Some(params) = params {
            request = request.query(&params);
        }

        let response = request.send().await?;

        self.handle_response(response).await
    }

    pub async fn update<T: Serialize, R: for<'de> Deserialize<'de>>(
        &self,
        url: &str,
        payload: &T,
    ) -> Result<R, Box<dyn Error>> {
        let url = self.get_url(url);
        let response = self
            .client
            .put(url)
            .basic_auth(&self.api_key, Some(&self.api_secret))
            .json(payload)
            .send()
            .await?;

        self.handle_response(response).await
    }

    pub async fn delete<R: for<'de> Deserialize<'de>>(&self, url: &str) -> Result<R, Box<dyn Error>> {
        let url = self.get_url(url);
        let response = self
            .client
            .delete(url)
            .basic_auth(&self.api_key, Some(&self.api_secret))
            .send()
            .await?;

        self.handle_response(response).await
    }

    async fn handle_response<R: for<'de> Deserialize<'de>>(
        &self,
        response: reqwest::Response,
    ) -> Result<R, Box<dyn Error>> {
        let status = response.status();
        let body = response.text().await?;

        if status.is_success() {
            Ok(serde_json::from_str(&body)?)
        } else {
            Err(Box::new(LightspeedApiError {
                message: body,
                status_code: status.as_u16(),
            }))
        }
    }
}