tsfile 0.0.2

Apache IoTDB TsFile written in Rust
Documentation
use std::borrow::BorrowMut;
use std::convert::TryFrom;
use std::io::Cursor;

use crate::utils::cursor;
use crate::utils::cursor::VarIntReader;
use byteorder::{BigEndian, ReadBytesExt};
use snafu::{ResultExt, Snafu};
use varint::VarintRead;

#[derive(Debug, Snafu)]
pub enum Error {
    #[snafu(display("Unable to read unsigned VarInt data: {}", source))]
    ReadUnsignedVarInt { source: std::io::Error },
    #[snafu(display("Unable to read cursor data: {}", source))]
    ReadCursorData { source: std::io::Error },
    #[snafu(display("Unable to read cursor data: {}", source))]
    ReadVarData { source: cursor::Error },
}

#[derive(Debug)]
pub enum Statistic {
    Boolean(BooleanStatistics),
    Int32(IntegerStatistics),
    Int64(LongStatistics),
    FLOAT(FloatStatistics),
    DOUBLE(DoubleStatistics),
    TEXT(BinaryStatistics),
}

#[derive(Debug)]
pub struct StatisticHeader {
    is_empty: bool,
    count: i32,
    start_time: i64,
    end_time: i64,
}

#[derive(Debug)]
pub struct BinaryStatistics {
    header: StatisticHeader,
    first_value: String,
    last_value: String,
}

#[derive(Debug)]
pub struct BooleanStatistics {
    header: StatisticHeader,
    first_value: bool,
    last_value: bool,
    sum_value: i64,
}

#[derive(Debug)]
pub struct IntegerStatistics {
    header: StatisticHeader,
    min_value: i32,
    max_value: i32,
    first_value: i32,
    last_value: i32,
    sum_value: i64,
}

#[derive(Debug)]
pub struct LongStatistics {
    header: StatisticHeader,
    min_value: i64,
    max_value: i64,
    first_value: i64,
    last_value: i64,
    sum_value: f64,
}

#[derive(Debug)]
pub struct DoubleStatistics {
    header: StatisticHeader,
    min_value: f64,
    max_value: f64,
    first_value: f64,
    last_value: f64,
    sum_value: f64,
}

#[derive(Debug)]
pub struct FloatStatistics {
    header: StatisticHeader,
    min_value: f32,
    max_value: f32,
    first_value: f32,
    last_value: f32,
    sum_value: f64,
}

impl TryFrom<&mut Cursor<Vec<u8>>> for StatisticHeader {
    type Error = Error;

    fn try_from(cursor: &mut Cursor<Vec<u8>>) -> Result<Self, Self::Error> {
        let count = cursor
            .read_unsigned_varint_32()
            .context(ReadUnsignedVarInt)? as i32;
        let start_time = cursor.read_i64::<BigEndian>().context(ReadCursorData)?;
        let end_time = cursor.read_i64::<BigEndian>().context(ReadCursorData)?;
        Ok(Self {
            count,
            start_time,
            end_time,
            is_empty: false,
        })
    }
}

impl TryFrom<&mut Cursor<Vec<u8>>> for BooleanStatistics {
    type Error = Error;

    fn try_from(cursor: &mut Cursor<Vec<u8>>) -> Result<Self, Self::Error> {
        Ok(Self {
            header: StatisticHeader::try_from(cursor.borrow_mut())?,
            first_value: cursor.read_bool().context(ReadVarData)?,
            last_value: cursor.read_bool().context(ReadVarData)?,
            sum_value: cursor.read_i64::<BigEndian>().context(ReadCursorData)?,
        })
    }
}

impl TryFrom<&'_ mut Cursor<Vec<u8>>> for IntegerStatistics {
    type Error = Error;

    fn try_from(cursor: &'_ mut Cursor<Vec<u8>>) -> Result<Self, Self::Error> {
        Ok(Self {
            header: StatisticHeader::try_from(cursor.borrow_mut())?,
            min_value: cursor.read_i32::<BigEndian>().context(ReadCursorData)?,
            max_value: cursor.read_i32::<BigEndian>().context(ReadCursorData)?,
            first_value: cursor.read_i32::<BigEndian>().context(ReadCursorData)?,
            last_value: cursor.read_i32::<BigEndian>().context(ReadCursorData)?,
            sum_value: cursor.read_i64::<BigEndian>().context(ReadCursorData)?,
        })
    }
}

impl TryFrom<&'_ mut Cursor<Vec<u8>>> for FloatStatistics {
    type Error = Error;

    fn try_from(cursor: &'_ mut Cursor<Vec<u8>>) -> Result<Self, Self::Error> {
        Ok(Self {
            header: StatisticHeader::try_from(cursor.borrow_mut())?,
            min_value: cursor.read_f32::<BigEndian>().context(ReadCursorData)?,
            max_value: cursor.read_f32::<BigEndian>().context(ReadCursorData)?,
            first_value: cursor.read_f32::<BigEndian>().context(ReadCursorData)?,
            last_value: cursor.read_f32::<BigEndian>().context(ReadCursorData)?,
            sum_value: cursor.read_f64::<BigEndian>().context(ReadCursorData)?,
        })
    }
}

impl TryFrom<&'_ mut Cursor<Vec<u8>>> for DoubleStatistics {
    type Error = Error;

    fn try_from(cursor: &'_ mut Cursor<Vec<u8>>) -> Result<Self, Self::Error> {
        Ok(Self {
            header: StatisticHeader::try_from(cursor.borrow_mut())?,
            min_value: cursor.read_f64::<BigEndian>().context(ReadCursorData)?,
            max_value: cursor.read_f64::<BigEndian>().context(ReadCursorData)?,
            first_value: cursor.read_f64::<BigEndian>().context(ReadCursorData)?,
            last_value: cursor.read_f64::<BigEndian>().context(ReadCursorData)?,
            sum_value: cursor.read_f64::<BigEndian>().context(ReadCursorData)?,
        })
    }
}

impl TryFrom<&'_ mut Cursor<Vec<u8>>> for LongStatistics {
    type Error = Error;

    fn try_from(cursor: &'_ mut Cursor<Vec<u8>>) -> Result<Self, Self::Error> {
        Ok(Self {
            header: StatisticHeader::try_from(cursor.borrow_mut())?,
            min_value: cursor.read_i64::<BigEndian>().context(ReadCursorData)?,
            max_value: cursor.read_i64::<BigEndian>().context(ReadCursorData)?,
            first_value: cursor.read_i64::<BigEndian>().context(ReadCursorData)?,
            last_value: cursor.read_i64::<BigEndian>().context(ReadCursorData)?,
            sum_value: cursor.read_f64::<BigEndian>().context(ReadCursorData)?,
        })
    }
}

impl TryFrom<&'_ mut Cursor<Vec<u8>>> for BinaryStatistics {
    type Error = Error;

    fn try_from(_value: &'_ mut Cursor<Vec<u8>>) -> Result<Self, Self::Error> {
        todo!()
    }
}