dlhn 0.1.7

DLHN is a blazing fast and small data serialization format.
Documentation
use crate::de::Error;
use serde::{
    de::{self, SeqAccess, Unexpected, Visitor},
    ser::SerializeTuple,
    Deserialize, Serialize,
};

const DATE_YEAR_OFFSET: i32 = 2000;
const DATE_ORDINAL_OFFSET: u16 = 1;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct Date {
    year: i32,
    ordinal: u16,
}

#[cfg(feature = "time")]
impl From<time::Date> for Date {
    fn from(date: time::Date) -> Self {
        Self {
            year: date.year(),
            ordinal: date.ordinal(),
        }
    }
}

#[cfg(feature = "time")]
impl std::convert::TryInto<time::Date> for Date {
    type Error = ();

    fn try_into(self) -> Result<time::Date, Self::Error> {
        time::Date::from_ordinal_date(self.year, self.ordinal).or(Err(()))
    }
}

impl Serialize for Date {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        let mut tuple = serializer.serialize_tuple(2)?;
        tuple.serialize_element(&(self.year - DATE_YEAR_OFFSET))?;
        tuple.serialize_element(&(self.ordinal - DATE_ORDINAL_OFFSET))?;
        tuple.end()
    }
}

struct DateVisitor;

impl<'de> Visitor<'de> for DateVisitor {
    type Value = Date;

    fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
        formatter.write_str("format error")
    }

    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
    where
        A: SeqAccess<'de>,
    {
        let year = seq
            .next_element::<i32>()?
            .ok_or(de::Error::invalid_value(Unexpected::Seq, &Error::Read))?
            + DATE_YEAR_OFFSET;
        let ordinal = seq
            .next_element::<u16>()?
            .ok_or(de::Error::invalid_value(Unexpected::Seq, &Error::Read))?
            + DATE_ORDINAL_OFFSET;
        Ok(Date { year, ordinal })
    }
}

impl<'de> Deserialize<'de> for Date {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        deserializer.deserialize_tuple(2, DateVisitor)
    }
}

#[cfg(feature = "time")]
#[cfg(test)]
mod tests {
    use super::Date;
    use crate::{Deserializer, PrefixVarint, Serializer, ZigZag};
    use serde::{Deserialize, Serialize};
    use std::convert::TryInto;

    #[test]
    fn from() {
        let date = Date::from(time::Date::from_ordinal_date(2020, 12).unwrap());
        assert_eq!(
            date,
            Date {
                year: 2020,
                ordinal: 12,
            }
        );
    }

    #[test]
    fn try_into() {
        let date = Date::from(time::Date::from_ordinal_date(2020, 12).unwrap());
        let time_date: time::Date = date.try_into().unwrap();
        assert_eq!(time_date, time::Date::from_ordinal_date(2020, 12).unwrap());
    }

    #[test]
    fn serialize_date() {
        assert_eq!(
            serialize(Date::from(time::Date::from_ordinal_date(2000, 1).unwrap())),
            [
                0i32.encode_zigzag().encode_prefix_varint_vec(),
                0u16.encode_prefix_varint_vec()
            ]
            .concat(),
        );
        assert_eq!(
            serialize(Date::from(time::Date::from_ordinal_date(1936, 1).unwrap())),
            [
                (1936i32 - 2000).encode_zigzag().encode_prefix_varint_vec(),
                0u16.encode_prefix_varint_vec()
            ]
            .concat(),
        );
        assert_eq!(
            serialize(Date::from(time::Date::from_ordinal_date(1935, 1).unwrap())),
            [
                (1935i32 - 2000).encode_zigzag().encode_prefix_varint_vec(),
                0u16.encode_prefix_varint_vec()
            ]
            .concat(),
        );
        assert_eq!(
            serialize(Date::from(
                time::Date::from_ordinal_date(2063, 128).unwrap()
            )),
            [
                (2063i32 - 2000).encode_zigzag().encode_prefix_varint_vec(),
                127u16.encode_prefix_varint_vec()
            ]
            .concat(),
        );
        assert_eq!(
            serialize(Date::from(
                time::Date::from_ordinal_date(2064, 129).unwrap()
            )),
            [
                (2064i32 - 2000).encode_zigzag().encode_prefix_varint_vec(),
                128u16.encode_prefix_varint_vec()
            ]
            .concat(),
        );
        assert_eq!(
            serialize(Date::from(
                time::Date::from_ordinal_date(2000, 366).unwrap()
            )),
            [
                (2000i32 - 2000).encode_zigzag().encode_prefix_varint_vec(),
                365u16.encode_prefix_varint_vec()
            ]
            .concat(),
        );
    }

    #[test]
    fn deserialize_date() {
        let buf = serialize(Date::from(
            time::Date::from_calendar_date(1970, time::Month::January, 11).unwrap(),
        ));
        let mut reader = buf.as_slice();
        let mut deserializer = Deserializer::new(&mut reader);
        assert_eq!(
            Date::deserialize(&mut deserializer).unwrap(),
            Date::from(time::Date::from_calendar_date(1970, time::Month::January, 11).unwrap())
        );
    }

    fn serialize<T: Serialize>(v: T) -> Vec<u8> {
        let mut buf = Vec::new();
        let mut serializer = Serializer::new(&mut buf);
        v.serialize(&mut serializer).unwrap();
        buf
    }
}