iso-4217 0.1.0

Currency code based on ISO-4217
Documentation
use iso_4217::CurrencyCode;
use serde::{self, Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
struct Object {
    #[serde(with = "str_curr_code")]
    str_code: CurrencyCode,

    #[serde(with = "num_curr_code")]
    num_code: CurrencyCode,
}

mod str_curr_code {
    use super::*;
    use serde::{Deserialize, Deserializer, Serializer};
    use std::convert::TryFrom;

    pub fn serialize<S>(v: &CurrencyCode, s: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        s.serialize_str((*v).into())
    }

    pub fn deserialize<'de, D>(d: D) -> Result<CurrencyCode, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(d)?;
        CurrencyCode::try_from(s.as_ref()).map_err(serde::de::Error::custom)
    }
}

mod num_curr_code {
    use super::*;
    use serde::{Deserialize, Deserializer, Serializer};
    use std::convert::TryFrom;

    pub fn serialize<S>(v: &CurrencyCode, s: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        s.serialize_u32((*v).into())
    }

    pub fn deserialize<'de, D>(d: D) -> Result<CurrencyCode, D::Error>
    where
        D: Deserializer<'de>,
    {
        let v = u32::deserialize(d)?;
        CurrencyCode::try_from(v).map_err(serde::de::Error::custom)
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let json: &[u8] = br#"{"str_code":"USD","num_code":392}"#;
    let obj = Object {
        str_code: CurrencyCode::USD,
        num_code: CurrencyCode::JPY,
    };

    assert_eq!(serde_json::from_slice::<Object>(json)?, obj);
    assert_eq!(serde_json::to_vec(&obj)?, json);

    Ok(())
}