rust-eureka 0.2.0

Simple Netflix Eureka Client
Documentation
use serde::de::{Deserialize, Deserializer, Error as DeError, Visitor};
use serde::ser::{Serialize, Serializer};
use std::convert::From;
use std::fmt;
use std::iter::Iterator;

const UP: &str = "UP";
const DOWN: &str = "DOWN";
const STARTING: &str = "STARTING";
const OUT_OF_SERVICE: &str = "OUT_OF_SERVICE";
const UNKNOWN: &str = "UNKNOWN";

#[derive(Debug, PartialEq)]
pub enum Status {
    Up,
    Down,
    Starting,
    OutOfService,
    Unknown,
}

impl Status {
    fn values() -> Vec<Status> {
        use self::Status::*;
        vec![Up, Down, Starting, OutOfService]
    }
}

impl From<&str> for Status {
    fn from(str: &str) -> Self {
        match str {
            UP => Status::Up,
            DOWN => Status::Down,
            STARTING => Status::Starting,
            OUT_OF_SERVICE => Status::OutOfService,
            _ => Status::Unknown,
        }
    }
}

impl From<String> for Status {
    fn from(s: String) -> Self {
        Status::from(s.as_ref())
    }
}

impl From<Status> for String {
    fn from(s: Status) -> Self {
        match s {
            Status::Up => UP.to_string(),
            Status::Down => DOWN.to_string(),
            Status::Starting => STARTING.to_string(),
            Status::OutOfService => OUT_OF_SERVICE.to_string(),
            _ => UNKNOWN.to_string(),
        }
    }
}

impl From<&Status> for String {
    fn from(s: &Status) -> Self {
        match *s {
            Status::Up => UP.to_string(),
            Status::Down => DOWN.to_string(),
            Status::Starting => STARTING.to_string(),
            Status::OutOfService => OUT_OF_SERVICE.to_string(),
            Status::Unknown => UNKNOWN.to_string(),
        }
    }
}

impl Serialize for Status {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(String::from(self).as_ref())
    }
}

impl<'de> Deserialize<'de> for Status {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct StatusVisitor;

        impl<'de> Visitor<'de> for StatusVisitor {
            type Value = Status;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                let values = Status::values().iter().fold(String::new(), |mut acc, v| {
                    acc.push_str(String::from(v).as_ref());
                    acc
                });

                formatter.write_fmt(format_args!("Expecting {}", values))
            }

            fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
            where
                E: DeError,
            {
                Ok(From::from(v))
            }
        }

        deserializer.deserialize_str(StatusVisitor)
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_from_string_ref() {
        let up = Status::from(UP);
        assert_eq!(Status::Up, up);
    }

    #[test]
    fn test_from_string() {
        let up = Status::from(UP.to_owned());
        assert_eq!(Status::Up, up);
    }
}