rgs_models 0.1.1

Tool for querying game servers. Models.
Documentation
#![feature(proc_macro)]

#[macro_use]
extern crate serde_derive;
use std::collections::HashMap;
use std::ops::Deref;
use std::str::FromStr;

extern crate serde;

extern crate iso_country;

use serde::*;

use iso_country::Country as CountryBase;

mod protocols;
use protocols::*;

#[derive(Clone, Debug, PartialEq)]
pub struct Country(CountryBase);

impl Deref for Country {
    type Target = iso_country::Country;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl Default for Country {
    fn default() -> Country {
        Country(CountryBase::Unspecified)
    }
}

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

impl Deserialize for Country {
    fn deserialize<D>(deserializer: &mut D) -> Result<Self, D::Error>
        where D: Deserializer
    {
        struct Visitor;
        impl de::Visitor for Visitor {
            type Value = Country;

            fn visit_str<E>(&mut self, value: &str) -> Result<Country, E>
                where E: de::Error
            {
                Ok(Country(CountryBase::from_str(value).unwrap_or(CountryBase::Unspecified)))
            }
        }
        deserializer.deserialize_str(Visitor)
    }
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub enum Status {
    Unspecified,
    Up,
    Down,
}

impl Default for Status {
    fn default() -> Status {
        Status::Unspecified
    }
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct Player {
    pub name: String,
    pub ping: i64,
    pub info: HashMap<String, String>,
}

#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
pub struct Server {
    // Mandatory parameters
    pub host: String,

    #[serde(default)]
    pub protocol: Protocol,

    #[serde(default)]
    pub status: Status,

    #[serde(default)]
    pub country: Country,

    #[serde(default)]
    pub rules: HashMap<String, String>,

    // Optional fields
    #[serde(skip_serializing_if="Option::is_none")]
    pub name: Option<String>,

    #[serde(skip_serializing_if="Option::is_none")]
    pub need_pass: Option<bool>,

    #[serde(skip_serializing_if="Option::is_none")]
    pub mod_name: Option<String>,

    #[serde(skip_serializing_if="Option::is_none")]
    pub game_type: Option<String>,

    #[serde(skip_serializing_if="Option::is_none")]
    pub terrain: Option<String>,

    #[serde(skip_serializing_if="Option::is_none")]
    pub num_clients: Option<i64>,

    #[serde(skip_serializing_if="Option::is_none")]
    pub max_clients: Option<i64>,

    #[serde(skip_serializing_if="Option::is_none")]
    pub num_bots: Option<i64>,

    #[serde(skip_serializing_if="Option::is_none")]
    pub secure: Option<bool>,

    #[serde(skip_serializing_if="Option::is_none")]
    pub ping: Option<i64>,

    #[serde(skip_serializing_if="Option::is_none")]
    pub players: Option<Vec<Player>>,
}

#[cfg(test)]
mod tests {
    use super::*;
    extern crate serde_json;

    #[test]
    fn serialization() {
        let myserver = Server {
            protocol: Protocol::Q3S,
            status: Status::Up,
            host: "127.0.0.1".to_string(),
            country: Country(CountryBase::RU),
            name: None,
            need_pass: None,
            mod_name: None,
            game_type: None,
            terrain: None,
            num_clients: None,
            max_clients: None,
            num_bots: None,
            secure: None,
            ping: None,
            players: None,
            rules: HashMap::new(),
        };

        assert_eq!(serde_json::to_string(&myserver).unwrap(), "{\"host\":\"127.0.0.1\",\"protocol\":\"Q3S\",\"status\":\"Up\",\"country\":\"RU\",\"rules\":{}}");
    }

    #[test]
    fn deserialization() {
        let myserver = Server {
            protocol: Protocol::Q3S,
            status: Status::Up,
            host: "127.0.0.1".to_string(),
            country: Country(CountryBase::RU),
            name: None,
            need_pass: None,
            mod_name: None,
            game_type: None,
            terrain: None,
            num_clients: None,
            max_clients: None,
            num_bots: None,
            secure: None,
            ping: None,
            players: None,
            rules: HashMap::new(),
        };

        assert_eq!(serde_json::from_str::<Server>("{\"protocol\":\"Q3S\",\"status\":\"Up\",\"host\":\"127.0.0.1\",\"country\":\"RU\",\"rules\":{}}").unwrap(), myserver);
    }
}