rotbl 0.2.10

Read Only Table
Documentation
use std::fmt;
use std::io;
use std::io::Error;
use std::io::Read;
use std::io::Write;

use codeq::FixedSize;

const VL_ARRAY: [u8; 8] = *b"vla\0\0\0\0\0";
const ROTBL: [u8; 8] = *b"rotbl\0\0\0";
const ROTBL_META: [u8; 8] = *b"rotbl_m\0";
const BLOCK: [u8; 8] = *b"blk\0\0\0\0\0";
const BLOCK_INDEX: [u8; 8] = *b"blk_idx\0";

#[derive(Debug)]
#[derive(Clone, Copy)]
#[derive(PartialEq, Eq)]
pub enum Type {
    VLArray,
    Rotbl,
    RotblMeta,
    Block,
    BlockIndex,
}

impl fmt::Display for Type {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl FixedSize for Type {
    fn encoded_size() -> usize {
        8
    }
}

impl codeq::Encode for Type {
    fn encode<W: Write>(&self, mut w: W) -> Result<usize, Error> {
        let b = match self {
            Type::VLArray => &VL_ARRAY,
            Type::Rotbl => &ROTBL,
            Type::RotblMeta => &ROTBL_META,
            Type::Block => &BLOCK,
            Type::BlockIndex => &BLOCK_INDEX,
        };
        w.write_all(b)?;

        Ok(b.len())
    }
}

impl codeq::Decode for Type {
    fn decode<R: Read>(mut r: R) -> Result<Self, Error> {
        let mut buf = [0u8; 8];
        r.read_exact(&mut buf)?;

        match buf {
            VL_ARRAY => Ok(Type::VLArray),
            ROTBL => Ok(Type::Rotbl),
            ROTBL_META => Ok(Type::RotblMeta),
            BLOCK => Ok(Type::Block),
            BLOCK_INDEX => Ok(Type::BlockIndex),
            _ => Err(Error::new(
                io::ErrorKind::InvalidData,
                format!("invalid type: {:?}", buf),
            )),
        }
    }
}

#[cfg(test)]
mod tests {
    use codeq::Decode;
    use codeq::Encode;

    use crate::typ::typ::BLOCK;
    use crate::typ::typ::BLOCK_INDEX;
    use crate::typ::typ::ROTBL;
    use crate::typ::typ::ROTBL_META;
    use crate::typ::typ::VL_ARRAY;
    use crate::typ::Type;

    #[test]
    fn test_type_codec() -> anyhow::Result<()> {
        {
            let mut b = Vec::new();
            let n = Type::VLArray.encode(&mut b)?;
            assert_eq!(n, 8);
            assert_eq!(b, VL_ARRAY);
            assert_eq!(Type::decode(&mut b.as_slice())?, Type::VLArray);
        }

        {
            let mut b = Vec::new();
            let n = Type::Rotbl.encode(&mut b)?;
            assert_eq!(n, 8);
            assert_eq!(b, ROTBL);
            assert_eq!(Type::decode(&mut b.as_slice())?, Type::Rotbl);
        }

        {
            let mut b = Vec::new();
            let n = Type::RotblMeta.encode(&mut b)?;
            assert_eq!(n, 8);
            assert_eq!(b, ROTBL_META);
            assert_eq!(Type::decode(&mut b.as_slice())?, Type::RotblMeta);
        }

        {
            let mut b = Vec::new();
            let n = Type::Block.encode(&mut b)?;
            assert_eq!(n, 8);
            assert_eq!(b, BLOCK);
            assert_eq!(Type::decode(&mut b.as_slice())?, Type::Block);
        }

        {
            let mut b = Vec::new();
            let n = Type::BlockIndex.encode(&mut b)?;
            assert_eq!(n, 8);
            assert_eq!(b, BLOCK_INDEX);
            assert_eq!(Type::decode(&mut b.as_slice())?, Type::BlockIndex);
        }
        Ok(())
    }
}