facture_rs 0.1.3

A wrapper for the FactureApp API service.
Documentation
use reqwest::header::{HeaderMap, HeaderValue, ACCEPT, AUTHORIZATION, CONTENT_TYPE};

use crate::{belling::utils::{core::{enums::BillingType, error::BillingError, response::BillingResponse}, json::input::JsonInput}, core::{cons::URI, request::FactureRequest}
};

pub struct JsonBilling;

impl FactureRequest for JsonBilling{
  type Input = JsonInput;
  type Output = BillingResponse;
  type TError = BillingError;

  async fn request(&self, input: JsonInput) -> Result<BillingResponse, BillingError>{
    let req_client = reqwest::Client::new();
    let endpoint = if input.bill_type == BillingType::JSON  {format!("{}/timbrado/json", URI)} else {format!("{}/timbrado/", URI)} ;

    let bearer = format!("Bearer {}", input.get_bearer());
    let mut headers = HeaderMap::new();
    let auth_header = bearer
      .parse::<HeaderValue>()
      .map_err(|error| BillingError::RequestSetup(format!("invalid authorization header: {error}")))?;
    headers.insert(AUTHORIZATION, auth_header);
    headers.insert(ACCEPT, HeaderValue::from_static("application/json"));
    headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json"));

    let json = input.get_json()?;

    let api_response = req_client
      .post(endpoint)
      .headers(headers)
      .query(&[("grant_type", "password")])
      .body(json)
      .send()
      .await?;

    if api_response.status().is_success(){
      let json = api_response.text().await?;
      println!("{}",json);
      let response: BillingResponse = serde_json::from_str(&json)?;
      return Ok(response);
    }
    else{
      let status = api_response.status().as_u16();
      let message = api_response
        .text()
        .await
        .unwrap_or_else(|error| format!("failed to read api error body: {error}"));

      return Err(
        BillingError::Api {
          status,
          message
        }
      )
    }
  }

}