ocpi 0.3.5

Unofficial, in progress, OCPI implementation
Documentation
use std::{fmt, str::FromStr};

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum Role {
    /// Charge Point Operator Role.
    Cpo,

    /// eMobility Service Provider Role.
    Emsp,

    /// Hub role.
    Hub,

    /// National Access Point Role (national Database with all Location information of a country).
    Nap,

    /// Navigation Service Provider Role, role like an eMSP
    /// (probably only interested in Location information).
    Nsp,

    /// Other role.
    Other,

    /// Smart Charging Service Provider Role.
    Scsp,
}

impl FromStr for Role {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "CPO" => Ok(Self::Cpo),
            "EMSP" => Ok(Self::Emsp),
            "HUB" => Ok(Self::Hub),
            "NAP" => Ok(Self::Nap),
            "NSP" => Ok(Self::Nsp),
            "OTHER" => Ok(Self::Other),
            "SCSP" => Ok(Self::Scsp),
            s => Err(format!("Invalid Role `{}`", s)),
        }
    }
}

impl fmt::Display for Role {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let s = match self {
            Self::Cpo => "CPO",
            Self::Emsp => "EMSP",
            Self::Hub => "HUB",
            Self::Nap => "NAP",
            Self::Nsp => "NSP",
            Self::Other => "OTHER",
            Self::Scsp => "SCSP",
        };

        f.write_str(s)
    }
}

impl serde::Serialize for Role {
    fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        match self {
            Self::Cpo => s.serialize_str("CPO"),
            Self::Emsp => s.serialize_str("EMSP"),
            Self::Hub => s.serialize_str("HUB"),
            Self::Nap => s.serialize_str("NAP"),
            Self::Nsp => s.serialize_str("NSP"),
            Self::Other => s.serialize_str("OTHER"),
            Self::Scsp => s.serialize_str("SCSP"),
        }
    }
}

impl<'de> serde::Deserialize<'de> for Role {
    fn deserialize<D>(deserializer: D) -> Result<Role, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_str(crate::common::FromStrVisitor::expecting("a valid Role"))
    }
}