idx_parser 0.3.0

Parse IDX files such as the ones used in MNIST database files.
Documentation
use crate::raw_data::*;
use std::{convert::TryInto, ops::Index};

pub type Row = Vec<Box<Matrix>>;

/// matrix which dynamically holds multidimensional data for an unspecified number of dimensions
/// each element in a Row is either a Data value or is another Row which holds further elements
/// elements can be extracted using .try_into()
#[derive(Debug, Clone, PartialEq)]
pub enum Matrix {
    Data(RawData),
    Row(Row),
}

#[derive(Debug, Copy, Clone)]
pub enum Error {
    NotAValue,
    NotARow,
    InvalidDataType,
}

impl TryInto<Row> for Matrix {
    type Error = Error;
    fn try_into(self) -> Result<Row, Self::Error> {
        if let Self::Row(x) = self {
            Ok(x)
        } else {
            Err(Error::NotARow)
        }
    }
}
impl TryInto<RawData> for Matrix {
    type Error = Error;
    fn try_into(self) -> Result<RawData, Self::Error> {
        if let Self::Data(x) = self {
            Ok(x)
        } else {
            Err(Error::NotAValue)
        }
    }
}
impl TryInto<u8> for Matrix {
    type Error = Error;
    fn try_into(self) -> Result<u8, Self::Error> {
        if let Self::Data(x) = self {
            let result: Result<u8, _> = x.try_into();
            if result.is_ok() {
                Ok(result.unwrap())
            } else {
                Err(Error::InvalidDataType)
            }
        } else {
            Err(Error::NotAValue)
        }
    }
}
impl TryInto<i8> for Matrix {
    type Error = Error;
    fn try_into(self) -> Result<i8, Self::Error> {
        if let Self::Data(x) = self {
            let result: Result<i8, _> = x.try_into();
            if result.is_ok() {
                Ok(result.unwrap())
            } else {
                Err(Error::InvalidDataType)
            }
        } else {
            Err(Error::NotAValue)
        }
    }
}
impl TryInto<i16> for Matrix {
    type Error = Error;
    fn try_into(self) -> Result<i16, Self::Error> {
        if let Self::Data(x) = self {
            let result: Result<i16, _> = x.try_into();
            if result.is_ok() {
                Ok(result.unwrap())
            } else {
                Err(Error::InvalidDataType)
            }
        } else {
            Err(Error::NotAValue)
        }
    }
}

impl TryInto<i32> for Matrix {
    type Error = Error;
    fn try_into(self) -> Result<i32, Self::Error> {
        if let Self::Data(x) = self {
            let result: Result<i32, _> = x.try_into();
            if result.is_ok() {
                Ok(result.unwrap())
            } else {
                Err(Error::InvalidDataType)
            }
        } else {
            Err(Error::NotAValue)
        }
    }
}
impl TryInto<f32> for Matrix {
    type Error = Error;
    fn try_into(self) -> Result<f32, Self::Error> {
        if let Self::Data(x) = self {
            let result: Result<f32, _> = x.try_into();
            if result.is_ok() {
                Ok(result.unwrap())
            } else {
                Err(Error::InvalidDataType)
            }
        } else {
            Err(Error::NotAValue)
        }
    }
}
impl TryInto<f64> for Matrix {
    type Error = Error;
    fn try_into(self) -> Result<f64, Self::Error> {
        if let Self::Data(x) = self {
            let result: Result<f64, _> = x.try_into();
            if result.is_ok() {
                Ok(result.unwrap())
            } else {
                Err(Error::InvalidDataType)
            }
        } else {
            Err(Error::NotAValue)
        }
    }
}
impl Index<usize> for Matrix {
    type Output = Self;
    fn index(&self, i: usize) -> &Self::Output {
        if let Self::Row(r) = self {
            &*r[i]
        } else {
            panic!("Index out of range")
        }
    }
}