use std::convert::From;
use std::fmt;
use std::io;
#[derive(Debug)]
pub enum StrategyDataTypes {
VecFloat32(Vec<f32>),
VecInt8(Vec<i8>),
VecInt16(Vec<i16>),
VecInt32(Vec<i32>),
VecString(Vec<String>),
VecChar(Vec<char>),
}
pub trait Strategy {
fn apply(&mut self) -> Result<StrategyDataTypes, EncodeError>;
}
#[derive(Debug)]
pub struct HeaderLayout {
pub codec: i32,
pub length: i32,
pub parameter: i32,
}
pub trait Header {
fn header(&mut self) -> Result<HeaderLayout, EncodeError>;
}
#[derive(Debug)]
pub enum EncodeError {
Codec(String),
Header(String),
Field,
Encoding(String),
IO(io::Error)
}
impl fmt::Display for EncodeError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
EncodeError::Codec(ref err) => write!(f, "Codec type `{}` doesn't exists", err),
EncodeError::Header(ref err) => write!(f, "Failed to parse Header: `{}`", err),
EncodeError::Field => write!(f, "Failed to parse Fields"),
EncodeError::Encoding(ref err) => write!(f, "encoding error: `{}`", err),
EncodeError::IO(ref err) => write!(f, "{}", err),
}
}
}
impl From<io::Error> for EncodeError {
fn from(error: io::Error) -> Self {
EncodeError::IO(error)
}
}
macro_rules! from_strategy_for {
($p:path, $type:ty) => {
impl From<StrategyDataTypes> for $type {
fn from(value: StrategyDataTypes) -> $type {
match value {
$p(some) => some,
_ => unreachable!()
}
}
}
impl From<StrategyDataTypes> for Option<$type> {
fn from(value: StrategyDataTypes) -> Option<$type> {
Some(From::from(value))
}
}
}
}
from_strategy_for!(StrategyDataTypes::VecChar, Vec<char>);
from_strategy_for!(StrategyDataTypes::VecString, Vec<String>);
from_strategy_for!(StrategyDataTypes::VecInt16, Vec<i16>);
from_strategy_for!(StrategyDataTypes::VecInt32, Vec<i32>);
from_strategy_for!(StrategyDataTypes::VecFloat32, Vec<f32>);
from_strategy_for!(StrategyDataTypes::VecInt8, Vec<i8>);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_convert_to_vec_i8() {
let data = StrategyDataTypes::VecInt8(vec![0_i8]);
let result: Vec<i8> = From::from(data);
assert_eq!(vec![0_i8], result);
let data = StrategyDataTypes::VecInt8(vec![0_i8]);
let result: Option<Vec<i8>> = From::from(data);
assert_eq!(Some(vec![0_i8]), result);
}
#[test]
fn it_convert_to_vec_i16() {
let data = StrategyDataTypes::VecInt16(vec![0_i16]);
let result: Vec<i16> = From::from(data);
assert_eq!(vec![0_i16], result);
}
#[test]
fn it_convert_to_vec_i32() {
let data = StrategyDataTypes::VecInt32(vec![0]);
let result: Vec<i32> = From::from(data);
assert_eq!(vec![0], result);
let data = StrategyDataTypes::VecInt32(vec![0]);
let result: Option<Vec<i32>> = From::from(data);
assert_eq!(Some(vec![0]), result);
}
#[test]
fn it_convert_to_vec_f32() {
let data = StrategyDataTypes::VecFloat32(vec![0.0]);
let result: Vec<f32> = From::from(data);
assert_eq!(vec![0.0], result);
let data = StrategyDataTypes::VecFloat32(vec![0.0]);
let result: Option<Vec<f32>> = From::from(data);
assert_eq!(Some(vec![0.0]), result);
}
#[test]
fn it_convert_to_vec_char() {
let data = StrategyDataTypes::VecChar(vec!['a']);
let result: Vec<char> = From::from(data);
assert_eq!(vec!['a'], result);
let data = StrategyDataTypes::VecChar(vec!['a']);
let result: Option<Vec<char>> = From::from(data);
assert_eq!(Some(vec!['a']), result);
}
#[test]
fn it_convert_to_vec_string() {
let data = StrategyDataTypes::VecString(vec!["A".to_string()]);
let result: Vec<String> = From::from(data);
assert_eq!(vec!["A".to_string()], result);
}
}