billecta 1.14.0

Generated Billecta API
Documentation
use std::fmt;

#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum CurrencyCode {
    Sek,
}

impl CurrencyCode {
    pub fn as_str(&self) -> &'static str {
        match self {
            Self::Sek => "SEK",
        }
    }
}

impl Default for CurrencyCode {
    fn default() -> Self {
        Self::Sek
    }
}

impl std::str::FromStr for CurrencyCode {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            s if s.eq_ignore_ascii_case("sek") => Ok(Self::Sek),
            s => Err(format!(
                "Invalid currency `{s}`. Supported currencies: [SEK]"
            )),
        }
    }
}

impl std::fmt::Display for CurrencyCode {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Self::Sek => write!(f, "SEK"),
        }
    }
}

impl serde::Serialize for CurrencyCode {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

struct Visitor;

impl<'de> serde::de::Visitor<'de> for Visitor {
    type Value = CurrencyCode;

    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        formatter.write_str(r#"a string containing a valid currency code"#)
    }

    fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
    where
        E: serde::de::Error,
    {
        use std::str::FromStr;

        CurrencyCode::from_str(s).map_err(E::custom)
    }

    fn visit_none<E>(self) -> Result<Self::Value, E>
    where
        E: serde::de::Error,
    {
        // @TODO: This allows us to work around Billecta bug.
        // doing it in deserialization however....
        Ok(CurrencyCode::Sek)
    }

    fn visit_some<D>(self, d: D) -> Result<Self::Value, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        d.deserialize_str(self)
    }
}

impl<'de> serde::Deserialize<'de> for CurrencyCode {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::de::Deserializer<'de>,
    {
        deserializer.deserialize_option(Visitor)
    }
}

#[cfg(test)]
mod tests {

    use super::*;
    use serde_json as js;

    #[test]
    fn serialize_currency() {
        assert_eq!(
            r#""SEK""#,
            js::to_string(&CurrencyCode::Sek).expect("Serializing")
        );
    }

    #[test]
    fn deserialize_currency() {
        assert_eq!(
            CurrencyCode::Sek,
            js::from_str(r#""SEK""#).expect("Deserializing")
        );
        assert_eq!(
            CurrencyCode::Sek,
            js::from_str(r#""sek""#).expect("Deserializing")
        );
        assert_eq!(
            CurrencyCode::Sek,
            js::from_str(r#""Sek""#).expect("Deserializing")
        );
        assert_eq!(
            CurrencyCode::Sek,
            js::from_str(r#""sEk""#).expect("Deserializing")
        );
        assert_eq!(
            CurrencyCode::Sek,
            js::from_str(r#""seK""#).expect("Deserializing")
        );
    }
}