dolphindb 3.3.1

A Rust native API for DolphinDB
Documentation
use crate::{
    error::{Error, Result},
    Serialize,
};
use bytes::BufMut;

use byteorder::{WriteBytesExt, BE, LE};

use crate::types::{any::Any, decimal::*, primitive::*, temporal::*};

impl Serialize for Void {
    fn serialize<B>(&self, buffer: &mut B) -> Result<usize>
    where
        B: bytes::BufMut,
    {
        let mut writer = buffer.writer();
        writer.write_i8(0).unwrap();
        Ok(0)
    }
}

impl Serialize for Bool {
    fn serialize<B>(&self, buffer: &mut B) -> Result<usize>
    where
        B: bytes::BufMut,
    {
        buffer.put_i8(self.as_ref().map(|b| b as i8).unwrap_or(i8::MIN));
        Ok(0)
    }
}

impl Serialize for Char {
    fn serialize<B>(&self, buffer: &mut B) -> Result<usize>
    where
        B: bytes::BufMut,
    {
        buffer.put_i8(self.as_ref().unwrap_or(i8::MIN));
        Ok(0)
    }
}

macro_rules! serialize_literal {
    ($struct_name:ident) => {
        impl Serialize for $struct_name {
            fn serialize<B>(&self, buffer: &mut B) -> Result<usize>
            where
                B: BufMut,
            {
                buffer.put(self.as_ref().as_ref().map(|s| s.as_str()).unwrap_or("").as_bytes());
                buffer.put_u8(b'\0');
                Ok(0)
            }
        }
    };

    ($($struct_name:ident), *) => {
        $(
            serialize_literal!($struct_name);
        )*
    };
}

serialize_literal!(DolphinString, Symbol);

macro_rules! serialize_primitive {
    ($raw_type:tt, $write_func:ident, $func_name:ident, $endian:tt) => {
        fn $func_name<B>(&self, buffer: &mut B) -> Result<usize>
        where
            B: bytes::BufMut,
        {
            let mut writer = buffer.writer();
            writer
                .$write_func::<$endian>(self.into_inner().unwrap_or($raw_type::MIN.into()).into())
                .unwrap();
            Ok(0)
        }
    };

    ($(($raw_type:tt, $struct_name:ident, $write_func:ident)), *) => {
        $(
            impl Serialize for $struct_name {
                serialize_primitive!($raw_type, $write_func, serialize, BE);
                serialize_primitive!($raw_type, $write_func, serialize_le, LE);
            }
        )*
    };
}

serialize_primitive!(
    (i16, Short, write_i16),
    (i32, Int, write_i32),
    (i64, Long, write_i64),
    (f32, Float, write_f32),
    (f64, Double, write_f64)
);

macro_rules! serialize_i32_temporal {
    ($func_name:ident, $offset:expr) => {
        fn $func_name<B>(&self, buffer: &mut B) -> Result<usize>
        where
            B: BufMut,
        {
            Int::from(self.elapsed().map(|i| i as i32 + $offset)).$func_name(buffer)
        }
    };

    ($(($struct_name:ident, $offset:expr)), *) => {
        $(
            impl Serialize for $struct_name {
                serialize_i32_temporal!(serialize, $offset);
                serialize_i32_temporal!(serialize_le, $offset);
            }
        )*
    }
}

macro_rules! serialize_i64_temporal {
    ($func_name:ident) => {
        fn $func_name<B>(&self, buffer: &mut B) -> Result<usize>
        where
            B: BufMut,
        {
            Long::from(self.elapsed().map(|i| i as i64)).$func_name(buffer)
        }
    };

    ($($struct_name:ident), *) => {
        $(
            impl Serialize for $struct_name {
                serialize_i64_temporal!(serialize);
                serialize_i64_temporal!(serialize_le);
            }
        )*
    }
}

serialize_i32_temporal!(
    (Date, 0),
    (Month, 23640),
    (Time, 0),
    (Minute, 0),
    (Second, 0),
    (DateTime, 0),
    (DateHour, 0)
);
serialize_i64_temporal!(Timestamp, NanoTime, NanoTimestamp);

macro_rules! serialize_decimal {
    ($raw_type:tt, $write_func:ident, $func_name:ident, $endian:tt) => {
        fn $func_name<B>(&self, buffer: &mut B) -> Result<usize>
        where
            B: bytes::BufMut,
        {
            let mut writer = buffer.writer();

            writer
                .write_i32::<$endian>(self.scale().unwrap_or(0) as i32)
                .unwrap();
            writer
                .$write_func::<$endian>(self.mantissa().unwrap_or($raw_type::MIN))
                .unwrap();
            Ok(0)
        }
    };

    ($(($raw_type:tt, $struct_name:ident, $write_func:ident)), *) => {
        $(
            impl Serialize for $struct_name {
                serialize_decimal!($raw_type, $write_func, serialize, BE);
                serialize_decimal!($raw_type, $write_func, serialize_le, LE);
            }
        )*
    };
}

serialize_decimal!(
    (i32, Decimal32, write_i32),
    (i64, Decimal64, write_i64),
    (i128, Decimal128, write_i128)
);

impl Serialize for Any {
    fn serialize<B>(&self, buffer: &mut B) -> Result<usize>
    where
        B: BufMut,
    {
        self.0.serialize(buffer)
    }

    fn serialize_le<B>(&self, buffer: &mut B) -> Result<usize>
    where
        B: BufMut,
    {
        self.0.serialize_le(buffer)
    }
}

impl Serialize for Blob {
    fn serialize<B>(&self, buffer: &mut B) -> Result<usize>
    where
        B: BufMut,
    {
        let phantom = Vec::with_capacity(0);
        let data = self.0.as_ref().unwrap_or(&phantom);
        let len =
            u32::try_from(data.len()).map_err(|e| Error::ConstraintsViolated(e.to_string()))?;

        buffer.put_u32(len);
        buffer.put(&data[..]);

        Ok(0)
    }

    fn serialize_le<B>(&self, buffer: &mut B) -> Result<usize>
    where
        B: BufMut,
    {
        let phantom = Vec::with_capacity(0);
        let data = self.0.as_ref().unwrap_or(&phantom);
        let len =
            u32::try_from(data.len()).map_err(|e| Error::ConstraintsViolated(e.to_string()))?;

        buffer.put_u32_le(len);
        buffer.put(&data[..]);

        Ok(0)
    }
}