use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
#[derive(Debug, PartialEq, Clone)]
pub enum GrupoCofins {
CofinsOutr(GrupoCofinsOutr),
CofinsNt(GrupoCofinsNt),
CofinsAliq(GrupoCofinsAliq),
}
impl<'de> Deserialize<'de> for GrupoCofins {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let grc = GrupoCofinsContainer::deserialize(deserializer)?;
if let Some(gr) = grc.cofins_outr {
return Ok(GrupoCofins::CofinsOutr(gr));
}
if let Some(gr) = grc.cofins_nt {
return Ok(GrupoCofins::CofinsNt(gr));
}
if let Some(gr) = grc.cofins_aliq {
return Ok(GrupoCofins::CofinsAliq(gr));
}
Err(Error::custom("Tipo de COFINS não suportado".to_string()))
}
}
impl Serialize for GrupoCofins {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let grc = match self {
GrupoCofins::CofinsOutr(g) => GrupoCofinsContainer {
cofins_outr: Some(g.clone()),
cofins_nt: None,
cofins_aliq: None,
},
GrupoCofins::CofinsNt(g) => GrupoCofinsContainer {
cofins_outr: None,
cofins_nt: Some(g.clone()),
cofins_aliq: None,
},
GrupoCofins::CofinsAliq(g) => GrupoCofinsContainer {
cofins_outr: None,
cofins_nt: None,
cofins_aliq: Some(g.clone()),
},
};
grc.serialize(serializer)
}
}
#[derive(Deserialize, Serialize)]
struct GrupoCofinsContainer {
#[serde(rename = "COFINSOutr")]
#[serde(skip_serializing_if = "Option::is_none")]
cofins_outr: Option<GrupoCofinsOutr>,
#[serde(rename = "COFINSNT")]
#[serde(skip_serializing_if = "Option::is_none")]
cofins_nt: Option<GrupoCofinsNt>,
#[serde(rename = "COFINSAliq")]
#[serde(skip_serializing_if = "Option::is_none")]
cofins_aliq: Option<GrupoCofinsAliq>,
}
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
pub struct GrupoCofinsOutr {
#[serde(rename = "$unflatten=CST")]
pub codigo_situacao: String,
#[serde(rename = "$unflatten=vBC")]
pub valor_base_calculo: f32,
#[serde(rename = "$unflatten=pCOFINS")]
pub aliquota: f32,
}
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
pub struct GrupoCofinsNt {
#[serde(rename = "$unflatten=CST")]
pub codigo_situacao: String,
}
#[derive(Debug, PartialEq, Deserialize, Serialize, Clone)]
pub struct GrupoCofinsAliq {
#[serde(rename = "$unflatten=CST")]
pub codigo_situacao: String,
#[serde(rename = "$unflatten=vBC")]
pub valor_base_calculo: f32,
#[serde(rename = "$unflatten=pCOFINS")]
pub aliquota: f32,
#[serde(rename = "$unflatten=vCOFINS")]
pub valor: f32,
}