<commit_before>use std::error;
use std::fmt::{self, Display};
use std::iter::Peekable;
use std::num;
use std::string;
use std::vec;

use redis::Value;

use serde::{self, de};

/// Error that can be produced during deserialization
#[derive(Debug)]
pub enum Error {
    Custom(String),
    EndOfStream,
    UnknownVariant(String, &'static [&'static str]),
    UnknownField(String, &'static [&'static str]),
    MissingField(&'static str),
    DuplicateField(&'static str),
    DeserializeNotSupported,
    WrongValue(String),
    FromUtf8(string::FromUtf8Error),
    ParseInt(num::ParseIntError),
    ParseFloat(num::ParseFloatError),
}

impl Error {
    pub fn wrong_value<S>(msg: S) -> Error
        where S: Into<String>
    {
        Error::WrongValue(msg.into())
    }
}

pub type Result<T> = ::std::result::Result<T, Error>;

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Custom(_) => "custom error when decoding redis values",
            Error::EndOfStream => "end of redis value stream",
            Error::UnknownField(..) => "unknown field",
            Error::UnknownVariant(..) => "unknown variant",
            Error::MissingField(_) => "missing field",
            Error::DuplicateField(_) => "duplicate field",
            Error::DeserializeNotSupported => "unsupported deserialization operation",
            Error::WrongValue(_) => "expected value of different type",
            Error::FromUtf8(ref err) => err.description(),
            Error::ParseInt(ref err) => err.description(),
            Error::ParseFloat(ref err) => err.description(),
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::FromUtf8(ref err) => Some(err),
            Error::ParseInt(ref err) => Some(err),
            Error::ParseFloat(ref err) => Some(err),
            _ => None,
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Custom(ref reason) => write!(f, "CustomError({})", reason),
            Error::EndOfStream => write!(f, "Reached end of stream"),
            Error::UnknownVariant(ref variant, ref expected) => {
                write!(f, "unexpected variant \"{}\"; expected {:?}", variant, expected)
            }
            Error::UnknownField(ref field, ref expected) => {
                write!(f, "unexpected field \"{}\"; expected {:?}", field, expected)
            }
            Error::MissingField(ref field) => write!(f, "missing field {:?}", field),
            Error::DuplicateField(ref field) => write!(f, "duplicate field {:?}", field),
            Error::DeserializeNotSupported => write!(f, "Deserialization option not supported"),
            Error::WrongValue(ref value_type) => write!(f, "Got unexpected value: {}", value_type),
            Error::FromUtf8(ref e) => write!(f, "{}", e),
            Error::ParseInt(ref e) => write!(f, "{}", e),
            Error::ParseFloat(ref e) => write!(f, "{}", e),
        }
    }
}

impl de::Error for Error {
    /// Raised when there is general error when deserializing a type.
    fn custom<T: Display>(msg: T) -> Self {
        Error::Custom(msg.to_string())
    }

    /// Raised when a `Deserialize` enum type received an unexpected variant.
    fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
        Error::UnknownVariant(variant.to_owned(), expected)
    }

    fn unknown_field(field: &str, expected: &'static [&'static str]) -> Error {
        Error::UnknownField(field.to_owned(), expected)
    }

    fn missing_field(field: &'static str) -> Error {
        Error::MissingField(field)
    }

    fn duplicate_field(field: &'static str) -> Error {
        Error::DuplicateField(field)
    }
}

impl From<string::FromUtf8Error> for Error {
    fn from(err: string::FromUtf8Error) -> Error {
        Error::FromUtf8(err)
    }
}

impl From<num::ParseIntError> for Error {
    fn from(err: num::ParseIntError) -> Error {
        Error::ParseInt(err)
    }
}

impl From<num::ParseFloatError> for Error {
    fn from(err: num::ParseFloatError) -> Error {
        Error::ParseFloat(err)
    }
}

/// deserializes Redis `Value`s
///
/// Deserializes a sequence of redis values. In the case of a Bulk value (eg, a
/// nested list), another deserializer is created for that sequence. The limit
/// to nested sequences is proportional to the maximum stack depth in current
/// machine.
///
/// If creating a Deserializer manually (ie not using `from_redis_value()`), the redis values must
/// first be placed in a Vec.
#[derive(Debug)]
pub struct Deserializer {
    values: Peekable<vec::IntoIter<Value>>,
}

pub trait IntoValueVec {
    fn into_value_vec(self) -> Vec<Value>;
}

impl IntoValueVec for Value {
    #[inline]
    fn into_value_vec(self) -> Vec<Value> {
        vec![self]
    }
}

impl IntoValueVec for Vec<Value> {
    #[inline]
    fn into_value_vec(self) -> Vec<Value> {
        self
    }
}

impl Deserializer {
    pub fn new<V>(values: V) -> Deserializer
        where V: IntoValueVec
    {
        Deserializer {
            values: values.into_value_vec().into_iter().peekable(),
        }
    }

    /// Returns a reference to the next value
    #[inline]
    pub fn peek(&mut self) -> Option<&Value> {
        self.values.peek()
    }

    /// Return the next value
    #[inline]
    pub fn next(&mut self) -> Result<Value> {
        match self.values.next() {
            Some(value) => Ok(value),
            None => Err(Error::EndOfStream)
        }
    }

    pub fn next_bulk(&mut self) -> Result<Vec<Value>> {
        match self.next()? {
            Value::Bulk(values) => Ok(values),
            v @ _ => Err(Error::wrong_value(format!("expected bulk but got {:?}", v)))
        }
    }

    pub fn read_string(&mut self) -> Result<String> {
        let redis_value = self.next()?;
        Ok(match redis_value {
            Value::Data(bytes) => String::from_utf8(bytes)?,
            _ => {
                let msg = format!("Expected Data, got {:?}", &redis_value);
                return Err(Error::wrong_value(msg));
            }
        })
    }
}

macro_rules! impl_num {
    ($ty:ty, $deserialize_method:ident, $visitor_method:ident) => {
        #[inline]
        fn $deserialize_method<V>(mut self, visitor: V) -> Result<V::Value>
            where V: de::Visitor<'de>,
        {

            let redis_value = self.next()?;
            let value = match redis_value {
                Value::Data(bytes) => {
                    let s = String::from_utf8(bytes)?;
                    s.parse::<$ty>()?
                },
                Value::Int(i) => i as $ty,
                _ => {
                    let msg = format!("Expected Data or Int, got {:?}", &redis_value);
                    return Err(Error::wrong_value(msg));
                }
            };

            visitor.$visitor_method(value)
        }
    }
}

macro_rules! default_deserialize {
    ($($name:ident)*) => {
        $(
            #[inline]
            fn $name<V>(self, visitor: V) -> Result<V::Value>
                where V: de::Visitor<'de>
            {
                self.deserialize_any(visitor)
            }
        )*
    }
}

impl<'de> serde::Deserializer<'de> for Deserializer {
    type Error = Error;

    #[inline]
    fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>,
    {
        let s = self.read_string()?;
        visitor.visit_str(&s[..])
    }

    #[inline]
    fn deserialize_string<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>,
    {
        let s = self.read_string()?;
        visitor.visit_string(s)
    }

    impl_num!(u8, deserialize_u8, visit_u8);
    impl_num!(u16, deserialize_u16, visit_u16);
    impl_num!(u32, deserialize_u32, visit_u32);
    impl_num!(u64, deserialize_u64, visit_u64);

    impl_num!(i8, deserialize_i8, visit_i8);
    impl_num!(i16, deserialize_i16, visit_i16);
    impl_num!(i32, deserialize_i32, visit_i32);
    impl_num!(i64, deserialize_i64, visit_i64);

    impl_num!(f32, deserialize_f32, visit_f32);
    impl_num!(f64, deserialize_f64, visit_f64);

    default_deserialize!(
        deserialize_str
        deserialize_char
        deserialize_bool
        deserialize_unit
    );

    #[inline]
    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        self.deserialize_seq(visitor)
    }

    #[inline]
    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        self.deserialize_seq(visitor)
    }

    #[inline]
    fn deserialize_tuple_struct<V>(self,
                                   _name: &'static str,
                                   len: usize,
                                   visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        self.deserialize_tuple(len, visitor)
    }

    #[inline]
    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        self.deserialize_seq(visitor)
    }

    #[inline]
    fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        let values = self.next_bulk()?;
        visitor.visit_seq(SeqVisitor { iter: values.into_iter() })
    }

    #[inline]
    fn deserialize_map<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        let values = self.next_bulk()?;
        visitor.visit_map(MapVisitor { iter: values.into_iter() })
    }

    #[inline]
    fn deserialize_unit_struct<V>(self,
                                  _name: &'static str,
                                  visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        self.deserialize_unit(visitor)
    }

    #[inline]
    fn deserialize_struct<V>(self,
                             _name: &'static str,
                             _fields: &'static [&'static str],
                             visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>,
    {
        self.deserialize_map(visitor)
    }

    #[inline]
    fn deserialize_ignored_any<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        let s = self.read_string()?;
        visitor.visit_str(&s[..])
    }

    #[inline]
    fn deserialize_enum<V>(mut self,
                           _enum: &'static str,
                           _variants: &'static [&'static str],
                           visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        visitor.visit_enum(EnumVisitor {
            variant: self.next()?,
            content: Value::Nil
        })
    }

    #[inline]
    fn deserialize_option<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        let maybe = match self.peek() {
            Some(v) => {
                match *v {
                    Value::Data(_) => Some(()),
                    Value::Int(_) => Some(()),
                    Value::Nil => None,
                    _ => {
                        let msg = format!("Expected Data, Int, or Nil");
                        return Err(Error::wrong_value(msg));
                    }
                }
            }
            None => None,
        };

        if maybe.is_some() {
            visitor.visit_some(self)
        } else {
            visitor.visit_none()
        }
    }

    #[inline]
    fn deserialize_newtype_struct<V>(self,
                                     _name: &'static str,
                                     visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        visitor.visit_newtype_struct(self)
    }

    #[inline]
    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de> {
        self.deserialize_str(visitor)
    }
}

struct SeqVisitor {
    iter: vec::IntoIter<Value>,
}

impl<'de> de::SeqAccess<'de> for SeqVisitor {
    type Error = Error;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
        where T: de::DeserializeSeed<'de>
    {
        match self.iter.next() {
            Some(v) => seed.deserialize(Deserializer::new(v)).map(Some),
            None => Ok(None)
        }
    }

    fn size_hint(&self) -> Option<usize> {
        self.iter.size_hint().1
    }
}

struct MapVisitor {
    iter: vec::IntoIter<Value>,
}

impl<'de> serde::de::MapAccess<'de> for MapVisitor {
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
        where K: de::DeserializeSeed<'de>,
    {
        match self.iter.next() {
            Some(v) => seed.deserialize(Deserializer::new(v)).map(Some),
            None => Ok(None)
        }
    }

    #[inline]
    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
        where V: de::DeserializeSeed<'de>,
    {
        match self.iter.next() {
            Some(v) => seed.deserialize(Deserializer::new(v)),
            None => Err(Error::EndOfStream),
        }
    }
}

struct VariantVisitor {
    value: Value,
}

impl<'de> serde::de::VariantAccess<'de> for VariantVisitor {
    type Error = Error;

    fn unit_variant(self) -> Result<()> {
        Ok(())
    }

    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
        where T: de::DeserializeSeed<'de>,
    {
        seed.deserialize(Deserializer::new(self.value))
    }

    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        use serde::Deserializer;
        let deserializer = self::Deserializer::new(self.value);
        deserializer.deserialize_any(visitor)
    }

    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        use serde::Deserializer;
        let deserializer = self::Deserializer::new(self.value);
        deserializer.deserialize_any(visitor)
    }
}

struct EnumVisitor {
    variant: Value,
    content: Value,
}

impl<'de> de::EnumAccess<'de> for EnumVisitor {
    type Error = Error;
    type Variant = VariantVisitor;

    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
        where V: de::DeserializeSeed<'de>
    {
        Ok((
            seed.deserialize(Deserializer::new(self.variant))?,
            VariantVisitor { value: self.content }
        ))
    }
}
<commit_msg>Add support for bool deserialization<commit_after>use std::error;
use std::fmt::{self, Display};
use std::iter::Peekable;
use std::num;
use std::string;
use std::vec;

use redis::Value;

use serde::{self, de};

/// Error that can be produced during deserialization
#[derive(Debug)]
pub enum Error {
    Custom(String),
    EndOfStream,
    UnknownVariant(String, &'static [&'static str]),
    UnknownField(String, &'static [&'static str]),
    MissingField(&'static str),
    DuplicateField(&'static str),
    DeserializeNotSupported,
    WrongValue(String),
    FromUtf8(string::FromUtf8Error),
    ParseInt(num::ParseIntError),
    ParseFloat(num::ParseFloatError),
}

impl Error {
    pub fn wrong_value<S>(msg: S) -> Error
        where S: Into<String>
    {
        Error::WrongValue(msg.into())
    }
}

pub type Result<T> = ::std::result::Result<T, Error>;

impl error::Error for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Custom(_) => "custom error when decoding redis values",
            Error::EndOfStream => "end of redis value stream",
            Error::UnknownField(..) => "unknown field",
            Error::UnknownVariant(..) => "unknown variant",
            Error::MissingField(_) => "missing field",
            Error::DuplicateField(_) => "duplicate field",
            Error::DeserializeNotSupported => "unsupported deserialization operation",
            Error::WrongValue(_) => "expected value of different type",
            Error::FromUtf8(ref err) => err.description(),
            Error::ParseInt(ref err) => err.description(),
            Error::ParseFloat(ref err) => err.description(),
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match *self {
            Error::FromUtf8(ref err) => Some(err),
            Error::ParseInt(ref err) => Some(err),
            Error::ParseFloat(ref err) => Some(err),
            _ => None,
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::Custom(ref reason) => write!(f, "CustomError({})", reason),
            Error::EndOfStream => write!(f, "Reached end of stream"),
            Error::UnknownVariant(ref variant, ref expected) => {
                write!(f, "unexpected variant \"{}\"; expected {:?}", variant, expected)
            }
            Error::UnknownField(ref field, ref expected) => {
                write!(f, "unexpected field \"{}\"; expected {:?}", field, expected)
            }
            Error::MissingField(ref field) => write!(f, "missing field {:?}", field),
            Error::DuplicateField(ref field) => write!(f, "duplicate field {:?}", field),
            Error::DeserializeNotSupported => write!(f, "Deserialization option not supported"),
            Error::WrongValue(ref value_type) => write!(f, "Got unexpected value: {}", value_type),
            Error::FromUtf8(ref e) => write!(f, "{}", e),
            Error::ParseInt(ref e) => write!(f, "{}", e),
            Error::ParseFloat(ref e) => write!(f, "{}", e),
        }
    }
}

impl de::Error for Error {
    /// Raised when there is general error when deserializing a type.
    fn custom<T: Display>(msg: T) -> Self {
        Error::Custom(msg.to_string())
    }

    /// Raised when a `Deserialize` enum type received an unexpected variant.
    fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
        Error::UnknownVariant(variant.to_owned(), expected)
    }

    fn unknown_field(field: &str, expected: &'static [&'static str]) -> Error {
        Error::UnknownField(field.to_owned(), expected)
    }

    fn missing_field(field: &'static str) -> Error {
        Error::MissingField(field)
    }

    fn duplicate_field(field: &'static str) -> Error {
        Error::DuplicateField(field)
    }
}

impl From<string::FromUtf8Error> for Error {
    fn from(err: string::FromUtf8Error) -> Error {
        Error::FromUtf8(err)
    }
}

impl From<num::ParseIntError> for Error {
    fn from(err: num::ParseIntError) -> Error {
        Error::ParseInt(err)
    }
}

impl From<num::ParseFloatError> for Error {
    fn from(err: num::ParseFloatError) -> Error {
        Error::ParseFloat(err)
    }
}

/// deserializes Redis `Value`s
///
/// Deserializes a sequence of redis values. In the case of a Bulk value (eg, a
/// nested list), another deserializer is created for that sequence. The limit
/// to nested sequences is proportional to the maximum stack depth in current
/// machine.
///
/// If creating a Deserializer manually (ie not using `from_redis_value()`), the redis values must
/// first be placed in a Vec.
#[derive(Debug)]
pub struct Deserializer {
    values: Peekable<vec::IntoIter<Value>>,
}

pub trait IntoValueVec {
    fn into_value_vec(self) -> Vec<Value>;
}

impl IntoValueVec for Value {
    #[inline]
    fn into_value_vec(self) -> Vec<Value> {
        vec![self]
    }
}

impl IntoValueVec for Vec<Value> {
    #[inline]
    fn into_value_vec(self) -> Vec<Value> {
        self
    }
}

impl Deserializer {
    pub fn new<V>(values: V) -> Deserializer
        where V: IntoValueVec
    {
        Deserializer {
            values: values.into_value_vec().into_iter().peekable(),
        }
    }

    /// Returns a reference to the next value
    #[inline]
    pub fn peek(&mut self) -> Option<&Value> {
        self.values.peek()
    }

    /// Return the next value
    #[inline]
    pub fn next(&mut self) -> Result<Value> {
        match self.values.next() {
            Some(value) => Ok(value),
            None => Err(Error::EndOfStream)
        }
    }

    pub fn next_bulk(&mut self) -> Result<Vec<Value>> {
        match self.next()? {
            Value::Bulk(values) => Ok(values),
            v @ _ => Err(Error::wrong_value(format!("expected bulk but got {:?}", v)))
        }
    }

    pub fn read_string(&mut self) -> Result<String> {
        let redis_value = self.next()?;
        Ok(match redis_value {
            Value::Data(bytes) => String::from_utf8(bytes)?,
            _ => {
                let msg = format!("Expected Data, got {:?}", &redis_value);
                return Err(Error::wrong_value(msg));
            }
        })
    }
}

macro_rules! impl_num {
    ($ty:ty, $deserialize_method:ident, $visitor_method:ident) => {
        #[inline]
        fn $deserialize_method<V>(mut self, visitor: V) -> Result<V::Value>
            where V: de::Visitor<'de>,
        {

            let redis_value = self.next()?;
            let value = match redis_value {
                Value::Data(bytes) => {
                    let s = String::from_utf8(bytes)?;
                    s.parse::<$ty>()?
                },
                Value::Int(i) => i as $ty,
                _ => {
                    let msg = format!("Expected Data or Int, got {:?}", &redis_value);
                    return Err(Error::wrong_value(msg));
                }
            };

            visitor.$visitor_method(value)
        }
    }
}

macro_rules! default_deserialize {
    ($($name:ident)*) => {
        $(
            #[inline]
            fn $name<V>(self, visitor: V) -> Result<V::Value>
                where V: de::Visitor<'de>
            {
                self.deserialize_any(visitor)
            }
        )*
    }
}

impl<'de> serde::Deserializer<'de> for Deserializer {
    type Error = Error;

    #[inline]
    fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>,
    {
        let s = self.read_string()?;
        visitor.visit_str(&s[..])
    }

    #[inline]
    fn deserialize_string<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>,
    {
        let s = self.read_string()?;
        visitor.visit_string(s)
    }

    impl_num!(u8, deserialize_u8, visit_u8);
    impl_num!(u16, deserialize_u16, visit_u16);
    impl_num!(u32, deserialize_u32, visit_u32);
    impl_num!(u64, deserialize_u64, visit_u64);

    impl_num!(i8, deserialize_i8, visit_i8);
    impl_num!(i16, deserialize_i16, visit_i16);
    impl_num!(i32, deserialize_i32, visit_i32);
    impl_num!(i64, deserialize_i64, visit_i64);

    impl_num!(f32, deserialize_f32, visit_f32);
    impl_num!(f64, deserialize_f64, visit_f64);

    default_deserialize!(
        deserialize_str
        deserialize_char
        deserialize_unit
    );

    #[inline]
    fn deserialize_bool<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>,
    {
        let s = self.read_string()?;

        let b = match s.as_str() {
            "1" | "true" | "True" => true,
            "0" | "false" | "False" => false,
            _ => return Err(Error::WrongValue(format!("Expected 1/0/true/false/True/False, got {}", s)))
        };

        visitor.visit_bool(b)
    }

    #[inline]
    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        self.deserialize_seq(visitor)
    }

    #[inline]
    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        self.deserialize_seq(visitor)
    }

    #[inline]
    fn deserialize_tuple_struct<V>(self,
                                   _name: &'static str,
                                   len: usize,
                                   visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        self.deserialize_tuple(len, visitor)
    }

    #[inline]
    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        self.deserialize_seq(visitor)
    }

    #[inline]
    fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        let values = self.next_bulk()?;
        visitor.visit_seq(SeqVisitor { iter: values.into_iter() })
    }

    #[inline]
    fn deserialize_map<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        let values = self.next_bulk()?;
        visitor.visit_map(MapVisitor { iter: values.into_iter() })
    }

    #[inline]
    fn deserialize_unit_struct<V>(self,
                                  _name: &'static str,
                                  visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        self.deserialize_unit(visitor)
    }

    #[inline]
    fn deserialize_struct<V>(self,
                             _name: &'static str,
                             _fields: &'static [&'static str],
                             visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>,
    {
        self.deserialize_map(visitor)
    }

    #[inline]
    fn deserialize_ignored_any<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        let s = self.read_string()?;
        visitor.visit_str(&s[..])
    }

    #[inline]
    fn deserialize_enum<V>(mut self,
                           _enum: &'static str,
                           _variants: &'static [&'static str],
                           visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        visitor.visit_enum(EnumVisitor {
            variant: self.next()?,
            content: Value::Nil
        })
    }

    #[inline]
    fn deserialize_option<V>(mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        let maybe = match self.peek() {
            Some(v) => {
                match *v {
                    Value::Data(_) => Some(()),
                    Value::Int(_) => Some(()),
                    Value::Nil => None,
                    _ => {
                        let msg = format!("Expected Data, Int, or Nil");
                        return Err(Error::wrong_value(msg));
                    }
                }
            }
            None => None,
        };

        if maybe.is_some() {
            visitor.visit_some(self)
        } else {
            visitor.visit_none()
        }
    }

    #[inline]
    fn deserialize_newtype_struct<V>(self,
                                     _name: &'static str,
                                     visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        visitor.visit_newtype_struct(self)
    }

    #[inline]
    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de> {
        self.deserialize_str(visitor)
    }
}

struct SeqVisitor {
    iter: vec::IntoIter<Value>,
}

impl<'de> de::SeqAccess<'de> for SeqVisitor {
    type Error = Error;

    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
        where T: de::DeserializeSeed<'de>
    {
        match self.iter.next() {
            Some(v) => seed.deserialize(Deserializer::new(v)).map(Some),
            None => Ok(None)
        }
    }

    fn size_hint(&self) -> Option<usize> {
        self.iter.size_hint().1
    }
}

struct MapVisitor {
    iter: vec::IntoIter<Value>,
}

impl<'de> serde::de::MapAccess<'de> for MapVisitor {
    type Error = Error;

    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
        where K: de::DeserializeSeed<'de>,
    {
        match self.iter.next() {
            Some(v) => seed.deserialize(Deserializer::new(v)).map(Some),
            None => Ok(None)
        }
    }

    #[inline]
    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
        where V: de::DeserializeSeed<'de>,
    {
        match self.iter.next() {
            Some(v) => seed.deserialize(Deserializer::new(v)),
            None => Err(Error::EndOfStream),
        }
    }
}

struct VariantVisitor {
    value: Value,
}

impl<'de> serde::de::VariantAccess<'de> for VariantVisitor {
    type Error = Error;

    fn unit_variant(self) -> Result<()> {
        Ok(())
    }

    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
        where T: de::DeserializeSeed<'de>,
    {
        seed.deserialize(Deserializer::new(self.value))
    }

    fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        use serde::Deserializer;
        let deserializer = self::Deserializer::new(self.value);
        deserializer.deserialize_any(visitor)
    }

    fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
        where V: de::Visitor<'de>
    {
        use serde::Deserializer;
        let deserializer = self::Deserializer::new(self.value);
        deserializer.deserialize_any(visitor)
    }
}

struct EnumVisitor {
    variant: Value,
    content: Value,
}

impl<'de> de::EnumAccess<'de> for EnumVisitor {
    type Error = Error;
    type Variant = VariantVisitor;

    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
        where V: de::DeserializeSeed<'de>
    {
        Ok((
            seed.deserialize(Deserializer::new(self.variant))?,
            VariantVisitor { value: self.content }
        ))
    }
}
<|endoftext|>


<commit_before>use std::result;

pub type Result<T> = result::Result<T, &'static str>;

/// get 4 indexes of ALPHABET table and return 3 ACII charaters
fn decode_block(block: &[u8]) -> [u8; 3] {
    let mut bitvec: u32 = 0xff_00_00_00;

    for (i, chr) in block.iter().enumerate() {
        let x: u32 = (*chr as u32) << (6 * (3 - i));
        bitvec |= x;
    }

    let mut res: [u8; 3] = [0; 3];
    let mut mask: u32 = 0x00_ff_00_00;

    for i in 0..3 {
        res[i] = ((bitvec & mask) >> (8 * (2 - i))) as u8;
        mask = mask >> 8;
    }
    res
}

pub fn decode(table: &[u8], data: &[u8]) -> Result<Vec<u8>> {
    let mut data = data.iter();
    let mut block: [u8; 4] = [0; 4];
    let mut res = Vec::new();

    loop {
        let mut skip = 0;

        // fill block with chars
        for i in 0..4 {
            block[i] = match data.next() {
                Some(&chr) => {
                    let idx = table[chr as usize];
                    let chr = chr as char;

                    if chr == '=' {
                        skip += 1;
                    }

                    if idx == 0 && !(chr == 'A' || chr == '=') {
                        return Err("Invalid character");
                    };

                    idx
                },
                None => {
                    if i != 0 {
                        return Err("Invalid padding");
                    } else {
                        return Ok(res);
                    }
                },
            }
        }
        let decoded = &decode_block(&block);
        for &idx in decoded[..3 - skip].iter() {
            res.push(idx);
        }
    }
}
<commit_msg>fix decoder<commit_after>use std::result;

pub type Result<T> = result::Result<T, &'static str>;

/// get 4 indexes of ALPHABET table and return 3 ACII charaters
fn decode_block(block: &[u8]) -> [u8; 3] {
    let mut bitvec: u32 = 0xff_00_00_00;

    for (i, chr) in block.iter().enumerate() {
        let x: u32 = (*chr as u32) << (6 * (3 - i));
        bitvec |= x;
    }

    let mut res: [u8; 3] = [0; 3];
    let mut mask: u32 = 0x00_ff_00_00;

    for i in 0..3 {
        res[i] = ((bitvec & mask) >> (8 * (2 - i))) as u8;
        mask = mask >> 8;
    }
    res
}

pub fn decode(table: &[u8], data: &[u8]) -> Result<Vec<u8>> {
    let mut data = data.iter().filter(|&&x| x != '\n' as u8);
    let mut block: [u8; 4] = [0; 4];
    let mut res = Vec::new();

    loop {
        let mut skip = 0;

        // fill block with chars
        for i in 0..4 {
            block[i] = match data.next() {
                Some(&chr) => {
                    let idx = table[chr as usize];
                    let chr = chr as char;

                    if chr == '=' {
                        skip += 1;
                    }

                    if idx == 0 && !(chr == 'A' || chr == '=') {
                        return Err("Invalid character");
                    };

                    idx
                },
                None => {
                    if i != 0 {
                        return Err("Invalid padding");
                    } else {
                        return Ok(res);
                    }
                },
            }
        }
        let decoded = &decode_block(&block);
        for &idx in decoded[..3 - skip].iter() {
            res.push(idx);
        }
    }
}
<|endoftext|>


<commit_before>// This file contains basic definitions for AIs as well as helper function to build them.
// Some example AIs are also contained.
extern crate rand;
use self::rand::{thread_rng, Rng};
//use self::rand::distributions::{IndependentSample, Range};
use game;
use game::{GameState, GameStructure, PlayerColor, VictoryState, VictoryStats, LineState, Action};

pub trait SogoAI {
    fn reset_game(&self);
    // Some information may be preserved after an opponent's turn.
    // Tree based algorithms may carry over part of the search tree.
    fn register_opponent_action(&self, &Action);
    fn decide_action(&self, state : &GameState) -> Action;
        // An imutable reference to the game_state is passed for convenience only.
}

pub fn run_match<T : SogoAI, U : SogoAI>(structure : &GameStructure, white_player : &T, black_player : &U) -> GameState {
    let mut i = 0;

    let mut state = GameState::new();
    while state.victory_state == VictoryState::Undecided {
        if state.age == 64 {
            state.victory_state = VictoryState::Draw;
            return state;
        }
        let action = if i % 2 == 0 {white_player.decide_action(&state)} else {black_player.decide_action(&state)};
        if i % 2 == 0 {black_player.register_opponent_action(&action)} else {white_player.register_opponent_action(&action)};
        state.execute_action(structure, &action);
        i += 1;
    }
    // println!("{:?}", i);
    return state;
}

// An AI which executes random legal actions
#[allow(dead_code)] // Empty structs are unstable.
pub struct RandomSogoAI {
    alibi : i8,
}

#[allow(dead_code)]
impl RandomSogoAI {
    pub fn new() -> RandomSogoAI {
        RandomSogoAI { alibi : 42 }
    }
}

impl SogoAI for RandomSogoAI {
    fn reset_game(&self) { }
    fn register_opponent_action(&self, _ : &Action) {}
    fn decide_action(&self, state : &GameState) -> Action {
        thread_rng().choose(&state.legal_actions)
            .map_or(Action::Surrender, |&a| a.clone())
        // Rust also implements a faster random generator, but it needs to be stored outside of this
        // small function. Caching the RNG might help anyways.
    }
}

pub fn random_playout(structure : &GameStructure, state : &GameState) -> VictoryState {
    let mut my_state = state.clone();
    let mut rng = thread_rng();
    while my_state.victory_state == VictoryState::Undecided {
        let surrender = Action::Surrender;
        let action = rng.choose(&my_state.legal_actions)
                        .unwrap_or(&surrender).clone();
        my_state.execute_action(structure, &action);
    }
    return my_state.victory_state;
}

pub fn random_playout_sample(structure : &GameStructure, state : &GameState, number : i32) -> VictoryStats {
    let mut statics = game::VictoryStats::new();
    for _ in 0..number {
        let result = random_playout(&structure, &state);
        match result {
            game::VictoryState::Win(game::PlayerColor::White) => statics.white += 1,
            game::VictoryState::Win(game::PlayerColor::Black) => statics.black += 1,
            game::VictoryState::Draw      => statics.draws  += 1,
            game::VictoryState::Undecided => panic!("The game_state should never be undecided after a random playout."),
        }
    }
    return statics
}

fn easy_judgement (state : &GameState, my_color : PlayerColor) -> i32 {
    let mut score = 0;
    for i in 0..76 {
        let line = state.lines[i];
        score += match line {
            LineState::Empty  => 0,
            LineState::Win(color) => 1000 * (if color == my_color {1} else {-1}),
                // If I'm still allowed to play, that must have been my win.
            LineState::Mixed  => 0,
            LineState::Pure { color, count } =>
                (count * count * (if color == my_color {1} else {-1})) as i32,
        }
    }
    return score
}

#[allow(dead_code)]
pub struct TreeJudgementAI {
    structure : game::GameStructure,
    search_depth : i8,
}

#[allow(dead_code)]
impl TreeJudgementAI {
    pub fn new(depth : i8) -> TreeJudgementAI {
        TreeJudgementAI { structure : game::GameStructure::new(), search_depth : depth }
    }
}

impl SogoAI for TreeJudgementAI {
    fn reset_game(&self) {}
    fn register_opponent_action(&self, _ : &Action) {}
    fn decide_action(&self, state : &GameState) -> Action {
        let my_color = state.current_color;
        // Create a tree from the current gamestate.
        let mut tree : Node<MinMaxTagging> = Node::new(state.clone(), None);
        // Completely expand the first n layers
        tree.fully_expand_to_depth(&self.structure, self.search_depth);

        let my_easy_judgement = |state : &GameState|
            MinMaxTagging { value : easy_judgement(state, my_color), from_action : None};

        tree.tag_all_leaves(&my_easy_judgement);
        min_max(&mut tree);

        let action = tree.tag.from_action.unwrap_or(Action::Surrender);
        println!("{:?} deciding on '{:?}' with valuation {:?}.", my_color, action, tree.tag.value);
        return action;
    }
}

// The type parameter T can carry additional information (like a score) and needs to allow a default.
struct Node<T : Default> {
    state : GameState,
    children : Branching<T>,
    parent_action : Option<Action>, // If this isn't the root, how did we get here?
    tag : T,
}

enum Branching<T : Default> {
    GameOver,
    Unexpanded,
    Expanded(Vec<Node<T>>),
}

impl<T : Default> Node<T> {
    pub fn new(state : GameState, parent_action : Option<Action>) -> Node<T> {
        Node {
            state : state,
            children : Branching::Unexpanded,
            parent_action : parent_action,
            tag : Default::default(),
        }
    }

    // Expands the current supplied node, if neccessary. The return value indicates if it was expanded.
    fn expand_total(&mut self, structure : &GameStructure) -> bool {
        match self.children {
            Branching::Unexpanded => {
                let mut children = Vec::new();
                for action in &self.state.legal_actions {
                    let mut child = Node::new(
                        self.state.execute_action_functional(structure, &action),
                        Some(action.clone())
                    );
                    if child.state.victory_state != VictoryState::Undecided {
                        child.children = Branching::GameOver;
                    }
                    children.push(child);
                }
                if children.len() == 0 {
                    self.children = Branching::GameOver;
                } else {
                    self.children = Branching::Expanded(children);
                }
                true
            },
            Branching::Expanded(_) => false,
            Branching::GameOver => false,
        }
    }

    fn fully_expand_to_depth(&mut self, structure : &GameStructure, depth : i8) {
        if depth <= 0 {
            return;
        }
        self.expand_total(structure);
        match self.children {
            Branching::Expanded(ref mut children) => {
                for mut child in children {
                    child.fully_expand_to_depth(structure, depth-1);
                }
            },
            _ => (),
        }
    }

    fn tag_all_leaves<F>(&mut self, tagger : &F)
    where F : Fn(&GameState) -> T {
        match self.children {
            Branching::GameOver   => self.tag = tagger(&self.state),
            Branching::Unexpanded => self.tag = tagger(&self.state),
            Branching::Expanded(ref mut children) => {
                for mut child in children {
                    child.tag_all_leaves(tagger);
                }
            }
        }
    }
}

#[derive(Default, Debug)]
struct MinMaxTagging {
    value : i32,
    from_action : Option<Action>,
}

fn min_max(node : &mut Node<MinMaxTagging>) {
    match node.children {
        Branching::Expanded(ref mut children) => {
            let mut max = i32::min_value();
            let mut action = None;
            for mut child in children {
                max_min(&mut child);
                if child.tag.value > max {
                    max = child.tag.value;
                    action = child.parent_action;
                }
            }
            node.tag.value = max;
            node.tag.from_action = action;
        },
        _ => () // Leaves don't min-max
    }
}

fn max_min(node : &mut Node<MinMaxTagging>) {
    match node.children {
        Branching::Expanded(ref mut children) => {
            let mut min = i32::max_value();
            let mut action = None;
            for mut child in children {
                min_max(&mut child);
                if child.tag.value < min {
                    min = child.tag.value;
                    action = child.parent_action;
                }
            }
            node.tag.value = min;
            node.tag.from_action = action;
        },
        _ => () // Leaves don't min-max
    }
}

// Pure Monte Carlo AI
// For each possible action, a number of playouts is run. This should give an approximate information
// about the value of each action.

#[allow(dead_code)]
pub struct MonteCarloAI {
    endurance : i32, // How many random games am I allowed to play each turn?
    structure : GameStructure,
}

#[allow(dead_code)]
impl MonteCarloAI {
    pub fn new(endurance : i32) -> MonteCarloAI {
        MonteCarloAI{endurance : endurance, structure : GameStructure::new()}
    }
}

impl SogoAI for MonteCarloAI {
    fn reset_game(&self) {}
    // Some information may be preserved after an opponent's turn.
    // Tree based algorithms may carry over part of the search tree.
    fn register_opponent_action(&self, _ : &Action) {}
    fn decide_action(&self, state : &GameState) -> Action {
        let my_color = state.current_color;
        let endurance_per_action = self.endurance / (state.legal_actions.len() as i32);
        // Create a tree from the current gamestate.
        let mut tree : Node<MinMaxTagging> = Node::new(state.clone(), None);
        // Completely expand the first layer
        tree.fully_expand_to_depth(&self.structure, 1);

        let judgement = |state : &GameState|
            MinMaxTagging {
                value : monte_carlo_judgement(&self.structure, state, my_color, endurance_per_action),
                from_action : None
            };

        tree.tag_all_leaves(&judgement);
        min_max(&mut tree);

        let action = tree.tag.from_action.unwrap_or(Action::Surrender);
        //println!("{:?} deciding on '{:?}' with valuation {:?}.", my_color, action, tree.tag.value);
        return action;
    }
}

fn monte_carlo_judgement(structure : &GameStructure, state : &GameState, my_color : PlayerColor, amount : i32) -> i32 {
    let stats = random_playout_sample(structure, state, amount);
    if my_color == PlayerColor::White {
        return stats.white - stats.black;
    } else {
        return stats.black - stats.white;
    }
}

/*
// Monte Carlo Tree search
// This is fancy, I'll do it later, when I learned about Monte Carlo and
// about Tree search.

// This tree structure is slightly more lazy than the Node tree and can expand a node partially.
struct MCNode {
    state : GameState,
    children : MCBranching,
    parent_action : Option<Action>, // If this isn't the root, how did we get here?
    wins : i32,
    total : i32,
}

enum LazyMCNode {
    Unexpanded(Action),
    // We need a Box to avoid [E0072], which forbids nested struct/enums.
    // use 'rustc --explain E0072' to find out more.
    Expanded(Box<MCNode>)
}

// I don't want to evaluate all possible branches to save time and memory.
// Only the possible actions are stored and can be lazily changed to a gamestate.
enum MCBranching {
    GameOver(VictoryState),
    Branch(Vec<LazyMCNode>),
}

impl MCNode {
    pub fn new(state : GameState, parent_action : Option<Action>) -> MCNode {
        let children = {
            if state.victory_state == VictoryState::Undecided {
                let mut children = Vec::new();
                for point in state.legal_actions {
                    children.push(LazyMCNode::Unexpanded(Action::new(&point)));
                }
                MCBranching::Branch(children)
            } else {
                MCBranching::GameOver(state.victory_state.clone())
            }
        };
        MCNode {
            state : state,
            children : children,
            parent_action : parent_action,
            wins : 0,
            total : 0,
        }
    }
}

fn random_mc_playout(structure : &GameStructure, node : &mut MCNode) -> VictoryState {
    // First, check if we have children.
    match node.children {
        MCBranching::GameOver(victory_state) => victory_state,
        MCBranching::Branch(mut children) => {
            // Randomly choose a child
            //let mut child = thread_rng().choose(&children).unwrap();
            // OK, here we have a problem with the saveness of Rust.
            // We can't own children and a child at the same time. This is kind of the reason why
            // choosing randomly can only return a reference to the child.
            // I'll try fixing this by choosing a random index first and then extracting that child.
            // That should give me ownership of a child and suspend children until the reference to
            // child becomes invalid. (At the end of this match block.)
            let between = Range::new(0, children.len());
            let index = between.ind_sample(&mut thread_rng());
            let mut child = children[index];
            match child {
                // if this is a unexpanded node, do a random playout, count it and propagate it upwards.
                LazyMCNode::Unexpanded(action) => {
                    let mut new_state = node.state.clone();
                    game::execute_action(structure, &mut new_state, action);
                    // This is bad, we clone the state twice.
                    // TODO: Define random_playout_ip to speed this up.
                    random_playout(structure, &mut new_state)
                }
                LazyMCNode::Expanded(boxed_node) => {
                    VictoryState::Draw
                }
            }
        }
    }
}
*/
<commit_msg>More changes to the unfinished Monte Carlo Tree Search.<commit_after>// This file contains basic definitions for AIs as well as helper function to build them.
// Some example AIs are also contained.
extern crate rand;
use self::rand::{thread_rng, Rng};
use self::rand::distributions::{IndependentSample, Range};
use game;
use game::{GameState, GameStructure, PlayerColor, VictoryState, VictoryStats, LineState, Action};

pub trait SogoAI {
    fn reset_game(&self);
    // Some information may be preserved after an opponent's turn.
    // Tree based algorithms may carry over part of the search tree.
    fn register_opponent_action(&self, &Action);
    fn decide_action(&self, state : &GameState) -> Action;
        // An imutable reference to the game_state is passed for convenience only.
}

pub fn run_match<T : SogoAI, U : SogoAI>(structure : &GameStructure, white_player : &T, black_player : &U) -> GameState {
    let mut i = 0;

    let mut state = GameState::new();
    while state.victory_state == VictoryState::Undecided {
        if state.age == 64 {
            state.victory_state = VictoryState::Draw;
            return state;
        }
        let action = if i % 2 == 0 {white_player.decide_action(&state)} else {black_player.decide_action(&state)};
        if i % 2 == 0 {black_player.register_opponent_action(&action)} else {white_player.register_opponent_action(&action)};
        state.execute_action(structure, &action);
        i += 1;
    }
    // println!("{:?}", i);
    return state;
}

// An AI which executes random legal actions
#[allow(dead_code)] // Empty structs are unstable.
pub struct RandomSogoAI {
    alibi : i8,
}

#[allow(dead_code)]
impl RandomSogoAI {
    pub fn new() -> RandomSogoAI {
        RandomSogoAI { alibi : 42 }
    }
}

impl SogoAI for RandomSogoAI {
    fn reset_game(&self) { }
    fn register_opponent_action(&self, _ : &Action) {}
    fn decide_action(&self, state : &GameState) -> Action {
        thread_rng().choose(&state.legal_actions)
            .map_or(Action::Surrender, |&a| a.clone())
        // Rust also implements a faster random generator, but it needs to be stored outside of this
        // small function. Caching the RNG might help anyways.
    }
}

pub fn random_playout(structure : &GameStructure, state : &GameState) -> VictoryState {
    let mut my_state = state.clone();
    let mut rng = thread_rng();
    while my_state.victory_state == VictoryState::Undecided {
        let surrender = Action::Surrender;
        let action = rng.choose(&my_state.legal_actions)
                        .unwrap_or(&surrender).clone();
        my_state.execute_action(structure, &action);
    }
    return my_state.victory_state;
}

pub fn random_playout_sample(structure : &GameStructure, state : &GameState, number : i32) -> VictoryStats {
    let mut statics = game::VictoryStats::new();
    for _ in 0..number {
        let result = random_playout(&structure, &state);
        match result {
            game::VictoryState::Win(game::PlayerColor::White) => statics.white += 1,
            game::VictoryState::Win(game::PlayerColor::Black) => statics.black += 1,
            game::VictoryState::Draw      => statics.draws  += 1,
            game::VictoryState::Undecided => panic!("The game_state should never be undecided after a random playout."),
        }
    }
    return statics
}

fn easy_judgement (state : &GameState, my_color : PlayerColor) -> i32 {
    let mut score = 0;
    for i in 0..76 {
        let line = state.lines[i];
        score += match line {
            LineState::Empty  => 0,
            LineState::Win(color) => 1000 * (if color == my_color {1} else {-1}),
                // If I'm still allowed to play, that must have been my win.
            LineState::Mixed  => 0,
            LineState::Pure { color, count } =>
                (count * count * (if color == my_color {1} else {-1})) as i32,
        }
    }
    return score
}

#[allow(dead_code)]
pub struct TreeJudgementAI {
    structure : game::GameStructure,
    search_depth : i8,
}

#[allow(dead_code)]
impl TreeJudgementAI {
    pub fn new(depth : i8) -> TreeJudgementAI {
        TreeJudgementAI { structure : game::GameStructure::new(), search_depth : depth }
    }
}

impl SogoAI for TreeJudgementAI {
    fn reset_game(&self) {}
    fn register_opponent_action(&self, _ : &Action) {}
    fn decide_action(&self, state : &GameState) -> Action {
        let my_color = state.current_color;
        // Create a tree from the current gamestate.
        let mut tree : Node<MinMaxTagging> = Node::new(state.clone(), None);
        // Completely expand the first n layers
        tree.fully_expand_to_depth(&self.structure, self.search_depth);

        let my_easy_judgement = |state : &GameState|
            MinMaxTagging { value : easy_judgement(state, my_color), from_action : None};

        tree.tag_all_leaves(&my_easy_judgement);
        min_max(&mut tree);

        let action = tree.tag.from_action.unwrap_or(Action::Surrender);
        println!("{:?} deciding on '{:?}' with valuation {:?}.", my_color, action, tree.tag.value);
        return action;
    }
}

// The type parameter T can carry additional information (like a score) and needs to allow a default.
struct Node<T : Default> {
    state : GameState,
    children : Branching<T>,
    parent_action : Option<Action>, // If this isn't the root, how did we get here?
    tag : T,
}

enum Branching<T : Default> {
    GameOver,
    Unexpanded,
    Expanded(Vec<Node<T>>),
}

impl<T : Default> Node<T> {
    pub fn new(state : GameState, parent_action : Option<Action>) -> Node<T> {
        Node {
            state : state,
            children : Branching::Unexpanded,
            parent_action : parent_action,
            tag : Default::default(),
        }
    }

    // Expands the current supplied node, if neccessary. The return value indicates if it was expanded.
    fn expand_total(&mut self, structure : &GameStructure) -> bool {
        match self.children {
            Branching::Unexpanded => {
                let mut children = Vec::new();
                for action in &self.state.legal_actions {
                    let mut child = Node::new(
                        self.state.execute_action_functional(structure, &action),
                        Some(action.clone())
                    );
                    if child.state.victory_state != VictoryState::Undecided {
                        child.children = Branching::GameOver;
                    }
                    children.push(child);
                }
                if children.len() == 0 {
                    self.children = Branching::GameOver;
                } else {
                    self.children = Branching::Expanded(children);
                }
                true
            },
            Branching::Expanded(_) => false,
            Branching::GameOver => false,
        }
    }

    fn fully_expand_to_depth(&mut self, structure : &GameStructure, depth : i8) {
        if depth <= 0 {
            return;
        }
        self.expand_total(structure);
        match self.children {
            Branching::Expanded(ref mut children) => {
                for mut child in children {
                    child.fully_expand_to_depth(structure, depth-1);
                }
            },
            _ => (),
        }
    }

    fn tag_all_leaves<F>(&mut self, tagger : &F)
    where F : Fn(&GameState) -> T {
        match self.children {
            Branching::GameOver   => self.tag = tagger(&self.state),
            Branching::Unexpanded => self.tag = tagger(&self.state),
            Branching::Expanded(ref mut children) => {
                for mut child in children {
                    child.tag_all_leaves(tagger);
                }
            }
        }
    }
}

#[derive(Default, Debug)]
struct MinMaxTagging {
    value : i32,
    from_action : Option<Action>,
}

fn min_max(node : &mut Node<MinMaxTagging>) {
    match node.children {
        Branching::Expanded(ref mut children) => {
            let mut max = i32::min_value();
            let mut action = None;
            for mut child in children {
                max_min(&mut child);
                if child.tag.value > max {
                    max = child.tag.value;
                    action = child.parent_action;
                }
            }
            node.tag.value = max;
            node.tag.from_action = action;
        },
        _ => () // Leaves don't min-max
    }
}

fn max_min(node : &mut Node<MinMaxTagging>) {
    match node.children {
        Branching::Expanded(ref mut children) => {
            let mut min = i32::max_value();
            let mut action = None;
            for mut child in children {
                min_max(&mut child);
                if child.tag.value < min {
                    min = child.tag.value;
                    action = child.parent_action;
                }
            }
            node.tag.value = min;
            node.tag.from_action = action;
        },
        _ => () // Leaves don't min-max
    }
}

// Pure Monte Carlo AI
// For each possible action, a number of playouts is run. This should give an approximate information
// about the value of each action.

#[allow(dead_code)]
pub struct MonteCarloAI {
    endurance : i32, // How many random games am I allowed to play each turn?
    structure : GameStructure,
}

#[allow(dead_code)]
impl MonteCarloAI {
    pub fn new(endurance : i32) -> MonteCarloAI {
        MonteCarloAI{endurance : endurance, structure : GameStructure::new()}
    }
}

impl SogoAI for MonteCarloAI {
    fn reset_game(&self) {}
    // Some information may be preserved after an opponent's turn.
    // Tree based algorithms may carry over part of the search tree.
    fn register_opponent_action(&self, _ : &Action) {}
    fn decide_action(&self, state : &GameState) -> Action {
        let my_color = state.current_color;
        let endurance_per_action = self.endurance / (state.legal_actions.len() as i32);
        // Create a tree from the current gamestate.
        let mut tree : Node<MinMaxTagging> = Node::new(state.clone(), None);
        // Completely expand the first layer
        tree.fully_expand_to_depth(&self.structure, 1);

        let judgement = |state : &GameState|
            MinMaxTagging {
                value : monte_carlo_judgement(&self.structure, state, my_color, endurance_per_action),
                from_action : None
            };

        tree.tag_all_leaves(&judgement);
        min_max(&mut tree);

        let action = tree.tag.from_action.unwrap_or(Action::Surrender);
        //println!("{:?} deciding on '{:?}' with valuation {:?}.", my_color, action, tree.tag.value);
        return action;
    }
}

fn monte_carlo_judgement(structure : &GameStructure, state : &GameState, my_color : PlayerColor, amount : i32) -> i32 {
    let stats = random_playout_sample(structure, state, amount);
    if my_color == PlayerColor::White {
        return stats.white - stats.black;
    } else {
        return stats.black - stats.white;
    }
}

// Monte Carlo Tree search
// This is fancy, I'll do it later, when I learned about Monte Carlo and
// about Tree search.

// This tree structure is slightly more lazy than the Node tree and can expand a node partially.
struct MCNode {
    state : GameState,
    children : MCBranching,
    parent_action : Option<Action>, // If this isn't the root, how did we get here?
    wins : i32,
    total : i32,
}

enum LazyMCNode {
    Unexpanded(Action),
    // We need a Box to avoid [E0072], which forbids nested struct/enums.
    // use 'rustc --explain E0072' to find out more.
    Expanded(Box<MCNode>)
}

// I don't want to evaluate all possible branches to save time and memory.
// Only the possible actions are stored and can be lazily changed to a gamestate.
enum MCBranching {
    GameOver(VictoryState),
    Branch(Vec<LazyMCNode>),
}

impl MCNode {
    pub fn new(state : GameState, parent_action : Option<Action>) -> MCNode {
        let children = {
            if state.victory_state == VictoryState::Undecided {
                let mut children = Vec::new();
                for action in &state.legal_actions {
                    children.push(LazyMCNode::Unexpanded(action.clone()));
                }
                MCBranching::Branch(children)
            } else {
                MCBranching::GameOver(state.victory_state.clone())
            }
        };
        MCNode {
            state : state,
            children : children,
            parent_action : parent_action,
            wins : 0,
            total : 0,
        }
    }
}

fn random_mc_playout(structure : &GameStructure, node : &mut MCNode) -> VictoryState {
    // First, check if we have children.
    match node.children {
        MCBranching::GameOver(victory_state) => victory_state,
        MCBranching::Branch(ref mut children) => {
            // Randomly choose a child
            //let mut child = thread_rng().choose(&children).unwrap();
            // OK, here we have a problem with the saveness of Rust.
            // We can't own children and a child at the same time. This is kind of the reason why
            // choosing randomly can only return a reference to the child.
            // I'll try fixing this by choosing a random index first and then extracting that child.
            // That should give me ownership of a child and suspend children until the reference to
            // child becomes invalid. (At the end of this match block.)
            let between = Range::new(0, children.len());
            let index = between.ind_sample(&mut thread_rng());
            let ref mut child = children[index];
            match child {
                // if this is a unexpanded node, do a random playout, count it and propagate it upwards.
                &mut LazyMCNode::Unexpanded(action) => {
                    let mut new_state = node.state.clone();
                    new_state.execute_action(structure, &action);
                    // This is bad, we clone the state twice.
                    // TODO: Define random_playout_ip to speed this up.
                    let result = random_playout(structure, &mut new_state);
                    result
                }
                &mut LazyMCNode::Expanded(ref mut boxed_node) => {
                    // Randomly choose a child to follow.
                    VictoryState::Draw
                }
            }
            //VictoryState::Draw
        }
    }
}
//*/
<|endoftext|>


<commit_before>use chrono::prelude::*;
use std::thread;

use command::*;
use database::DataBase;

pub struct Engine {
    next_wakeup: Option<DateTime<Utc>>,
    data_base: DataBase,
    callback : Option<(fn(String))>,
    stop_loop: bool,
}

impl Engine {
    pub fn new() -> Engine {
        info!("Initialize engine");
        Engine {
            stop_loop: false,
            next_wakeup: None,
            callback: None,
            data_base: DataBase::new(),
        }
    }

    // Normally should be run in another thread
    pub fn run(&mut self) {
        self.stop_loop = false;
        self.loop_thread();
    }

    fn loop_thread(&mut self) {
        info!("Start engine loop");
        while !self.stop_loop {
            self.tick();
            thread::sleep_ms(1000);
        }
    }

    fn tick(&mut self) {
        if self.next_wakeup.is_none() {
            self.next_wakeup = self.data_base.get_nearest_wakeup();
            return;
        }
        let next_wakeup = self.next_wakeup.unwrap();

        if Utc::now() > next_wakeup {
            if let Some(command) = self.data_base.pop(next_wakeup) {
                match command {
                    Command::OneTimeEvent(ev) => self.on_one_time_event(ev),
                    Command::RepetitiveEvent(ev) => self.on_repetitive_event(ev),
                    Command::BadCommand => warn!("Database::pop return BadCommand"),
                }
            }
            self.next_wakeup = self.data_base.get_nearest_wakeup();
        }
    }

    pub fn handle_text_message(&mut self, text_message: &str) -> String {
        info!("Handle text message : {}", text_message);
        let com = parse_command(String::from(text_message));
        match com {
            Command::BadCommand => self.process_bad_command(),
            Command::OneTimeEvent(ev) => self.process_one_time_event_command(ev),
            Command::RepetitiveEvent(ev) => self.process_repetitive_event_command(ev),
        }
    }

    pub fn register_callback(&mut self, f: fn(String)){
        self.callback = Some(f);
    }

    fn process_bad_command(&self) -> String {
        String::from("Can't parse input string")
    }

    fn process_one_time_event_command(&mut self, c: OneTimeEventImpl) -> String {
        let mut return_string = self.format_return_message_header(&c.event_time);
        return_string.push('\n');
        return_string.push_str(&c.event_text);
        self.data_base.put(Command::OneTimeEvent(c));
        self.next_wakeup = self.data_base.get_nearest_wakeup();

        // delete newline char to write to log
        let tmp_string = str::replace(&return_string[..], "\n", " ");
        info!("Successfully process command, return string - <{}>", tmp_string);

        return_string
    }

    fn process_repetitive_event_command(&mut self, c: RepetitiveEventImpl) -> String {
        String::from("Not implemented yet")
    }

    fn on_one_time_event(&self, event: OneTimeEventImpl){
        info!("Event time, text - <{}>", &event.event_text);
        (self.callback.unwrap())(event.event_text);
    }

    fn on_repetitive_event(&self, event: RepetitiveEventImpl){
        info!("Event time, text - <{}>", &event.event_text);
        (self.callback.unwrap())(event.event_text);
    }

    fn format_return_message_header(&self, event_time: &DateTime<Utc>) -> String {
        const DEFAULT_TZ : i32 = 3;
        let tz = FixedOffset::east(DEFAULT_TZ * 3600);
        let t_event = event_time.with_timezone(&tz);
        let t_now = Utc::now().with_timezone(&tz);

        if t_event < t_now {
            return String::from("Event time is in the past. Is it right?");
        }

        // days from year 1 TODO: maybe day of the year?
        let day_event = t_event.num_days_from_ce();
        let day_now = t_now.num_days_from_ce();
        let dt = day_event - day_now;

        if dt == 0 {
            return t_event.format("I'll remind you today at %H:%M").to_string();
        } else if dt == 1 {
            return t_event.format("I'll remind you tomorrow at %H:%M").to_string();
        }
        t_event.format("I'll remind you %B %e at %H:%M").to_string()
    }

    pub fn stop(&mut self) {
        info!("Stoping engine");
        self.stop_loop = true;
    }

    pub fn get_active_event_list(&self) -> Vec<String> {
        let mut result = Vec::new();
        let command_vector = self.data_base.get_all_active_events();
        for command in command_vector {
            match command {
                Command::OneTimeEvent(c) => {
                    let text: String = c.event_text.chars().take(40).collect();
                    let date: String = c.event_time.format("%c").to_string();
                    result.push(format!("{} : {}", date, text));
                }
                Command::BadCommand => {}
                Command::RepetitiveEvent(_ev) => {}
            }
        }
        result
    }
}
<commit_msg>Get rid of thread::sleep_ms warning<commit_after>use chrono::prelude::*;
use std::thread;
use std::time;

use command::*;
use database::DataBase;

pub struct Engine {
    next_wakeup: Option<DateTime<Utc>>,
    data_base: DataBase,
    callback : Option<(fn(String))>,
    stop_loop: bool,
}

impl Engine {
    pub fn new() -> Engine {
        info!("Initialize engine");
        Engine {
            stop_loop: false,
            next_wakeup: None,
            callback: None,
            data_base: DataBase::new(),
        }
    }

    // Normally should be run in another thread
    pub fn run(&mut self) {
        self.stop_loop = false;
        self.loop_thread();
    }

    fn loop_thread(&mut self) {
        info!("Start engine loop");
        while !self.stop_loop {
            self.tick();
            thread::sleep(time::Duration::from_millis(1000));
        }
    }

    fn tick(&mut self) {
        if self.next_wakeup.is_none() {
            self.next_wakeup = self.data_base.get_nearest_wakeup();
            return;
        }
        let next_wakeup = self.next_wakeup.unwrap();

        if Utc::now() > next_wakeup {
            if let Some(command) = self.data_base.pop(next_wakeup) {
                match command {
                    Command::OneTimeEvent(ev) => self.on_one_time_event(ev),
                    Command::RepetitiveEvent(ev) => self.on_repetitive_event(ev),
                    Command::BadCommand => warn!("Database::pop return BadCommand"),
                }
            }
            self.next_wakeup = self.data_base.get_nearest_wakeup();
        }
    }

    pub fn handle_text_message(&mut self, text_message: &str) -> String {
        info!("Handle text message : {}", text_message);
        let com = parse_command(String::from(text_message));
        match com {
            Command::BadCommand => self.process_bad_command(),
            Command::OneTimeEvent(ev) => self.process_one_time_event_command(ev),
            Command::RepetitiveEvent(ev) => self.process_repetitive_event_command(ev),
        }
    }

    pub fn register_callback(&mut self, f: fn(String)){
        self.callback = Some(f);
    }

    fn process_bad_command(&self) -> String {
        String::from("Can't parse input string")
    }

    fn process_one_time_event_command(&mut self, c: OneTimeEventImpl) -> String {
        let mut return_string = self.format_return_message_header(&c.event_time);
        return_string.push('\n');
        return_string.push_str(&c.event_text);
        self.data_base.put(Command::OneTimeEvent(c));
        self.next_wakeup = self.data_base.get_nearest_wakeup();

        // delete newline char to write to log
        let tmp_string = str::replace(&return_string[..], "\n", " ");
        info!("Successfully process command, return string - <{}>", tmp_string);

        return_string
    }

    fn process_repetitive_event_command(&mut self, c: RepetitiveEventImpl) -> String {
        String::from("Not implemented yet")
    }

    fn on_one_time_event(&self, event: OneTimeEventImpl){
        info!("Event time, text - <{}>", &event.event_text);
        (self.callback.unwrap())(event.event_text);
    }

    fn on_repetitive_event(&self, event: RepetitiveEventImpl){
        info!("Event time, text - <{}>", &event.event_text);
        (self.callback.unwrap())(event.event_text);
    }

    fn format_return_message_header(&self, event_time: &DateTime<Utc>) -> String {
        const DEFAULT_TZ : i32 = 3;
        let tz = FixedOffset::east(DEFAULT_TZ * 3600);
        let t_event = event_time.with_timezone(&tz);
        let t_now = Utc::now().with_timezone(&tz);

        if t_event < t_now {
            return String::from("Event time is in the past. Is it right?");
        }

        // days from year 1 TODO: maybe day of the year?
        let day_event = t_event.num_days_from_ce();
        let day_now = t_now.num_days_from_ce();
        let dt = day_event - day_now;

        if dt == 0 {
            return t_event.format("I'll remind you today at %H:%M").to_string();
        } else if dt == 1 {
            return t_event.format("I'll remind you tomorrow at %H:%M").to_string();
        }
        t_event.format("I'll remind you %B %e at %H:%M").to_string()
    }

    pub fn stop(&mut self) {
        info!("Stoping engine");
        self.stop_loop = true;
    }

    pub fn get_active_event_list(&self) -> Vec<String> {
        let mut result = Vec::new();
        let command_vector = self.data_base.get_all_active_events();
        for command in command_vector {
            match command {
                Command::OneTimeEvent(c) => {
                    let text: String = c.event_text.chars().take(40).collect();
                    let date: String = c.event_time.format("%c").to_string();
                    result.push(format!("{} : {}", date, text));
                }
                Command::BadCommand => {}
                Command::RepetitiveEvent(_ev) => {}
            }
        }
        result
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Anatoly Ikorsky
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use byteorder::{LittleEndian as LE, ReadBytesExt, WriteBytesExt};
use std::io;
use value::Value;

pub trait ReadMysqlExt: ReadBytesExt {
    /// Reads MySql's length-encoded integer.
    fn read_lenenc_int(&mut self) -> io::Result<u64> {
        match self.read_u8()? {
            0xfc => self.read_uint::<LE>(2),
            0xfd => self.read_uint::<LE>(3),
            0xfe => self.read_uint::<LE>(8),
            0xff => Err(io::Error::new(
                io::ErrorKind::Other,
                "Invalid length-encoded integer value",
            )),
            x => Ok(x as u64),
        }
    }
}

pub trait WriteMysqlExt: WriteBytesExt {
    /// Writes MySql's length-encoded integer.
    fn write_lenenc_int(&mut self, x: u64) -> io::Result<u64> {
        if x < 251 {
            self.write_u8(x as u8)?;
            Ok(1)
        } else if x < 65_536 {
            self.write_u8(0xFC)?;
            self.write_uint::<LE>(x, 2)?;
            Ok(3)
        } else if x < 16_777_216 {
            self.write_u8(0xFD)?;
            self.write_uint::<LE>(x, 3)?;
            Ok(4)
        } else {
            self.write_u8(0xFE)?;
            self.write_uint::<LE>(x, 8)?;
            Ok(9)
        }
    }

    /// Writes MySql's length-encoded string.
    fn write_lenenc_str(&mut self, bytes: &[u8]) -> io::Result<u64> {
        let written = self.write_lenenc_int(bytes.len() as u64)?;
        self.write_all(bytes)?;
        Ok(written + bytes.len() as u64)
    }

    /// Writes MySql's value in binary value format.
    fn write_bin_value(&mut self, value: &Value) -> io::Result<u64> {
        match *value {
            Value::NULL => Ok(0),
            Value::Bytes(ref x) => self.write_lenenc_str(&x[..]),
            Value::Int(x) => {
                self.write_i64::<LE>(x)?;
                Ok(8)
            }
            Value::UInt(x) => {
                self.write_u64::<LE>(x)?;
                Ok(8)
            }
            Value::Float(x) => {
                self.write_f64::<LE>(x)?;
                Ok(8)
            }
            Value::Date(0u16, 0u8, 0u8, 0u8, 0u8, 0u8, 0u32) => {
                self.write_u8(0u8)?;
                Ok(1)
            }
            Value::Date(y, m, d, 0u8, 0u8, 0u8, 0u32) => {
                self.write_u8(4u8)?;
                self.write_u16::<LE>(y)?;
                self.write_u8(m)?;
                self.write_u8(d)?;
                Ok(5)
            }
            Value::Date(y, m, d, h, i, s, 0u32) => {
                self.write_u8(7u8)?;
                self.write_u16::<LE>(y)?;
                self.write_u8(m)?;
                self.write_u8(d)?;
                self.write_u8(h)?;
                self.write_u8(i)?;
                self.write_u8(s)?;
                Ok(8)
            }
            Value::Date(y, m, d, h, i, s, u) => {
                self.write_u8(11u8)?;
                self.write_u16::<LE>(y)?;
                self.write_u8(m)?;
                self.write_u8(d)?;
                self.write_u8(h)?;
                self.write_u8(i)?;
                self.write_u8(s)?;
                self.write_u32::<LE>(u)?;
                Ok(12)
            }
            Value::Time(_, 0u32, 0u8, 0u8, 0u8, 0u32) => {
                self.write_u8(0u8)?;
                Ok(1)
            }
            Value::Time(neg, d, h, m, s, 0u32) => {
                self.write_u8(8u8)?;
                self.write_u8(if neg { 1u8 } else { 0u8 })?;
                self.write_u32::<LE>(d)?;
                self.write_u8(h)?;
                self.write_u8(m)?;
                self.write_u8(s)?;
                Ok(9)
            }
            Value::Time(neg, d, h, m, s, u) => {
                self.write_u8(12u8)?;
                self.write_u8(if neg { 1u8 } else { 0u8 })?;
                self.write_u32::<LE>(d)?;
                self.write_u8(h)?;
                self.write_u8(m)?;
                self.write_u8(s)?;
                self.write_u32::<LE>(u)?;
                Ok(13)
            }
        }
    }
}

impl<T> ReadMysqlExt for T
where
    T: ReadBytesExt,
{
}
impl<T> WriteMysqlExt for T
where
    T: WriteBytesExt,
{
}
<commit_msg>Rearrange match cases in read_lenenc_int<commit_after>// Copyright (c) 2017 Anatoly Ikorsky
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use byteorder::{LittleEndian as LE, ReadBytesExt, WriteBytesExt};
use std::io;
use value::Value;

pub trait ReadMysqlExt: ReadBytesExt {
    /// Reads MySql's length-encoded integer.
    fn read_lenenc_int(&mut self) -> io::Result<u64> {
        match self.read_u8()? {
            x if x < 0xfc => Ok(x as u64),
            0xfc => self.read_uint::<LE>(2),
            0xfd => self.read_uint::<LE>(3),
            0xfe => self.read_uint::<LE>(8),
            0xff => Err(io::Error::new(
                io::ErrorKind::Other,
                "Invalid length-encoded integer value",
            )),
            _ => unreachable!(),
        }
    }
}

pub trait WriteMysqlExt: WriteBytesExt {
    /// Writes MySql's length-encoded integer.
    fn write_lenenc_int(&mut self, x: u64) -> io::Result<u64> {
        if x < 251 {
            self.write_u8(x as u8)?;
            Ok(1)
        } else if x < 65_536 {
            self.write_u8(0xFC)?;
            self.write_uint::<LE>(x, 2)?;
            Ok(3)
        } else if x < 16_777_216 {
            self.write_u8(0xFD)?;
            self.write_uint::<LE>(x, 3)?;
            Ok(4)
        } else {
            self.write_u8(0xFE)?;
            self.write_uint::<LE>(x, 8)?;
            Ok(9)
        }
    }

    /// Writes MySql's length-encoded string.
    fn write_lenenc_str(&mut self, bytes: &[u8]) -> io::Result<u64> {
        let written = self.write_lenenc_int(bytes.len() as u64)?;
        self.write_all(bytes)?;
        Ok(written + bytes.len() as u64)
    }

    /// Writes MySql's value in binary value format.
    fn write_bin_value(&mut self, value: &Value) -> io::Result<u64> {
        match *value {
            Value::NULL => Ok(0),
            Value::Bytes(ref x) => self.write_lenenc_str(&x[..]),
            Value::Int(x) => {
                self.write_i64::<LE>(x)?;
                Ok(8)
            }
            Value::UInt(x) => {
                self.write_u64::<LE>(x)?;
                Ok(8)
            }
            Value::Float(x) => {
                self.write_f64::<LE>(x)?;
                Ok(8)
            }
            Value::Date(0u16, 0u8, 0u8, 0u8, 0u8, 0u8, 0u32) => {
                self.write_u8(0u8)?;
                Ok(1)
            }
            Value::Date(y, m, d, 0u8, 0u8, 0u8, 0u32) => {
                self.write_u8(4u8)?;
                self.write_u16::<LE>(y)?;
                self.write_u8(m)?;
                self.write_u8(d)?;
                Ok(5)
            }
            Value::Date(y, m, d, h, i, s, 0u32) => {
                self.write_u8(7u8)?;
                self.write_u16::<LE>(y)?;
                self.write_u8(m)?;
                self.write_u8(d)?;
                self.write_u8(h)?;
                self.write_u8(i)?;
                self.write_u8(s)?;
                Ok(8)
            }
            Value::Date(y, m, d, h, i, s, u) => {
                self.write_u8(11u8)?;
                self.write_u16::<LE>(y)?;
                self.write_u8(m)?;
                self.write_u8(d)?;
                self.write_u8(h)?;
                self.write_u8(i)?;
                self.write_u8(s)?;
                self.write_u32::<LE>(u)?;
                Ok(12)
            }
            Value::Time(_, 0u32, 0u8, 0u8, 0u8, 0u32) => {
                self.write_u8(0u8)?;
                Ok(1)
            }
            Value::Time(neg, d, h, m, s, 0u32) => {
                self.write_u8(8u8)?;
                self.write_u8(if neg { 1u8 } else { 0u8 })?;
                self.write_u32::<LE>(d)?;
                self.write_u8(h)?;
                self.write_u8(m)?;
                self.write_u8(s)?;
                Ok(9)
            }
            Value::Time(neg, d, h, m, s, u) => {
                self.write_u8(12u8)?;
                self.write_u8(if neg { 1u8 } else { 0u8 })?;
                self.write_u32::<LE>(d)?;
                self.write_u8(h)?;
                self.write_u8(m)?;
                self.write_u8(s)?;
                self.write_u32::<LE>(u)?;
                Ok(13)
            }
        }
    }
}

impl<T> ReadMysqlExt for T
where
    T: ReadBytesExt,
{
}
impl<T> WriteMysqlExt for T
where
    T: WriteBytesExt,
{
}
<|endoftext|>