Documentation
// All this is necessary because Serde decided that the best way
// to serialize an empty struct was as a null value, and the best way
// to deserialize it was as an empty list.  So instead we serialize it as a map.
macro_rules! serialize_empty {
    ($name: tt) => (
        serialize_empty_workaround!($name, $name);
    );
}

macro_rules! serialize_empty_workaround {
    ($name: ty, $obj: expr) => (
        impl serde::Serialize for $name {
            fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
                where S: serde::Serializer,
            {
                serializer.serialize_struct("", EmptyVisitor{})
            }
        }

        impl serde::de::Deserialize for $name {
            fn deserialize<D>(deserializer: &mut D) -> Result<$name, D::Error> where
             D: serde::de::Deserializer {
                {
                    struct Visitor;
                    impl serde::de::Visitor for Visitor {
                        type Value = $name;
                        #[inline]
                        fn visit_unit<E>(&mut self) -> Result<$name,E> where
                         E: serde::de::Error {
                            Ok($obj)
                        }
                        #[inline]
                        fn visit_map<V>(&mut self, mut visitor: V) -> Result<$name,V::Error>
                         where V: serde::de::MapVisitor {
                            try!(visitor.end());
                            self.visit_unit()
                        }
                    }
                    deserializer.deserialize_unit_struct("",Visitor)
                }
            }
        }
    );
}


mod options;
mod value;
mod error;
mod roles;

use serde;

pub use messages::types::options::*;
pub use messages::types::value::*;
pub use messages::types::error::*;
pub use messages::types::roles::*;

fn is_not(b: &bool) -> bool {
    !*b
}


/**************************
         Structs
**************************/




/// The policies that can be used for matching a uri pattern.
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum MatchingPolicy {
    /// The given pattern matches any URI that has it as a prefix
    Prefix,
    /// The given pattern contains at least one 'wildcard' segment which can match any segment at the same location
    Wildcard,
    /// The given pattern only matches URIs that are identical.
    Strict
}

/// The policies that dictate how invocations are distributed amongst shared registrations
#[derive(PartialEq, Debug, Clone, Copy)]
pub enum InvocationPolicy {
    // Only one reigistration per uri (the default)
    Single,
    // Callee selcted sequentially from the list of registrants
    RoundRobin,
    // Callee selcted randomly from the list of registrants
    Random,
    // First callee (in orer of registration) is called
    First,
    // Last callee (in order of registration( is called
    Last
}


/**************************
        Visitors
**************************/

struct MatchingPolicyVisitor;
struct InvocationPolicyVisitor;
struct EmptyVisitor;





impl MatchingPolicy {
    #[inline]
    fn is_strict(&self) -> bool {
        self == &MatchingPolicy::Strict
    }
}

impl InvocationPolicy {
    #[inline]
    fn is_single(&self) -> bool {
        self == &InvocationPolicy::Single
    }
}

impl Default for MatchingPolicy {
    #[inline]
    fn default() -> MatchingPolicy {
        MatchingPolicy::Strict
    }
}

impl Default for InvocationPolicy {
    #[inline]
    fn default() -> InvocationPolicy {
        InvocationPolicy::Single
    }
}

/**************************
 Serializers/Deserializers
**************************/
impl serde::ser::MapVisitor for EmptyVisitor {
    fn visit<S>(&mut self, _serializer: &mut S) -> Result<Option<()>, S::Error>
    where S: serde::Serializer
    {
        Ok(None)
    }

    fn len(&self) -> Option<usize> {
        Some(0)
    }
}


/*-------------------------
       MatchingPolicy
-------------------------*/

impl serde::Serialize for MatchingPolicy {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: serde::Serializer,
    {
        let ser_str = match *self {
             MatchingPolicy::Prefix => "prefix",
             MatchingPolicy::Wildcard => "wildcard",
             MatchingPolicy::Strict => ""
        };
        serializer.serialize_str(ser_str)
    }
}

impl serde::Deserialize for MatchingPolicy {
    fn deserialize<D>(deserializer: &mut D) -> Result<MatchingPolicy, D::Error>
        where D: serde::Deserializer,
    {
        deserializer.deserialize(MatchingPolicyVisitor)
    }
}

impl serde::de::Visitor for MatchingPolicyVisitor {
    type Value = MatchingPolicy;

    #[inline]
    fn visit_str<E>(&mut self, value: &str) -> Result<MatchingPolicy, E>
        where E: serde::de::Error,
    {
        match value {
            "prefix" => Ok(MatchingPolicy::Prefix),
            "wildcard" => Ok(MatchingPolicy::Wildcard),
            x => Err(serde::de::Error::custom(format!("Invalid matching policy: {}", x)))
        }
    }

}

impl serde::Serialize for InvocationPolicy {
    fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
        where S: serde::Serializer,
    {
        let ser_str = match *self {
             InvocationPolicy::Single => "single",
             InvocationPolicy::RoundRobin => "roundrobin",
             InvocationPolicy::Random => "random",
             InvocationPolicy::First => "first",
             InvocationPolicy::Last => "last",
        };
        serializer.serialize_str(ser_str)
    }
}

impl serde::Deserialize for InvocationPolicy {
    fn deserialize<D>(deserializer: &mut D) -> Result<InvocationPolicy, D::Error>
        where D: serde::Deserializer,
    {
        deserializer.deserialize(InvocationPolicyVisitor)
    }
}

impl serde::de::Visitor for InvocationPolicyVisitor {
    type Value = InvocationPolicy;

    #[inline]
    fn visit_str<E>(&mut self, value: &str) -> Result<InvocationPolicy, E>
        where E: serde::de::Error,
    {
        match value {
            "single" => Ok(InvocationPolicy::Single),
            "roundrobin" => Ok(InvocationPolicy::RoundRobin),
            "random" => Ok(InvocationPolicy::Random),
            "first" => Ok(InvocationPolicy::First),
            "last" => Ok(InvocationPolicy::Last),
            x => Err(serde::de::Error::custom(format!("Invalid invocation policy: {}", x)))
        }
    }

}