facture_rs 0.1.3

A wrapper for the FactureApp API service.
Documentation
use serde::{de, Deserialize, Deserializer};

#[derive(Deserialize, Debug, Clone, Default)]
pub struct BillingResponse{
  #[serde(default, deserialize_with = "deserialize_default_on_null")]
  pub success: bool,

  #[serde(default, deserialize_with = "deserialize_usize_from_string_or_number")]
  pub code: usize,

  #[serde(default, deserialize_with = "deserialize_default_on_null")]
  pub result: ResultData,

  #[serde(default, deserialize_with = "deserialize_default_on_null")]
  pub message: String
}


#[derive(Deserialize, Debug, Clone, Default)]
pub struct ResultData{
  #[serde(default, deserialize_with = "deserialize_default_on_null")]
  pub items: Vec<Item>,
}

#[derive(Debug, Deserialize, Clone, Default)]
pub struct Item {
  #[serde(rename = "requestUuid", default, deserialize_with = "deserialize_default_on_null")]
  pub request_uuid: String,

  #[serde(default, deserialize_with = "deserialize_default_on_null")]
  pub encode: String,

  #[serde(default, deserialize_with = "deserialize_default_on_null")]
  pub succeed: bool,

  #[serde(default, deserialize_with = "deserialize_default_on_null")]
  pub uuid: String,

  #[serde(default, deserialize_with = "deserialize_default_on_null")]
  pub message: String,
}

#[derive(Deserialize)]
#[serde(untagged)]
enum UsizeOrString {
  Usize(usize),
  String(String),
}

fn deserialize_usize_from_string_or_number<'de, D>(deserializer: D) -> Result<usize, D::Error>
where
  D: Deserializer<'de>,
{
  let value = Option::<UsizeOrString>::deserialize(deserializer)?;

  match value {
    Some(UsizeOrString::Usize(value)) => Ok(value),
    Some(UsizeOrString::String(value)) => value.parse::<usize>().map_err(de::Error::custom),
    None => Ok(0),
  }
}

fn deserialize_default_on_null<'de, D, T>(deserializer: D) -> Result<T, D::Error>
where
  D: Deserializer<'de>,
  T: Deserialize<'de> + Default,
{
  Option::<T>::deserialize(deserializer).map(|value| value.unwrap_or_default())
}