rustt 0.1.2

A wire-protocol for efficiently transfering self-describing data implemented in rust.
use crate::ttv3::serde::Type;
use serde::de as ser_de;
use serde::ser as ser_ser;
use std::fmt::{self, Display, Formatter};

#[derive(Debug)]
pub enum Error {
	// One or more variants that can be created by data structures through the
	// `ser::Error` and `de::Error` traits. For example the Serialize impl for
	// Mutex<T> might return an error because the mutex is poisoned, or the
	// Deserialize impl for a struct may return an error because a required
	// field is missing.
	Message(String),

	IOError(std::io::Error),
	UTF8Error(),

	OutOfSpace(),

	NeedsLength(),
	ImpossibleKey(Type),

	Expected((Type, Type)),

	Empty(),
}

impl Error {
	pub fn new(msg: &str) -> Self {
		Error::Message(String::from(msg))
	}
}

impl ser_ser::Error for Error {
	fn custom<T: Display>(msg: T) -> Self {
		Error::Message(msg.to_string())
	}
}

impl ser_de::Error for Error {
	fn custom<T: Display>(msg: T) -> Self {
		Error::Message(msg.to_string())
	}
}

impl Display for Error {
	fn fmt(&self, formatter: &mut Formatter) -> fmt::Result {
		let smth: String = match self {
			Error::Message(msg) => msg.clone(),
			Error::IOError(err) => {
				return err.fmt(formatter);
			}
			Error::UTF8Error() => String::from("invalid utf-8 was found while parsing a string"),

			Error::OutOfSpace() => {
				String::from("Not enought data in the reader to decode the TT value")
			}
			Error::NeedsLength() => {
				String::from("TT requires a known length before running encoding the slice/array")
			}
			Error::ImpossibleKey(got) => format!(
				"Cannot decode {} as a key in TT, TT can only encode basic types as key",
				got.as_str()
			),
			Error::Expected((expected, got)) => {
				if expected == &crate::ttv3::serde::STRING || expected == &crate::ttv3::serde::BYTES
				{
					format!("expected Bytes or String, got: {}", got.as_str())
				} else {
					format!("expected {}, got: {}", expected.as_str(), got.as_str())
				}
			}
			Error::Empty() => String::from("Empty types or none are not supported in TTv3"),
		};
		formatter.write_str(smth.as_str())
	}
}

impl std::error::Error for Error {}

impl std::convert::From<std::str::Utf8Error> for Error {
	fn from(_err: std::str::Utf8Error) -> Error {
		Error::UTF8Error()
	}
}

impl std::convert::From<std::io::Error> for Error {
	fn from(err: std::io::Error) -> Error {
		Error::IOError(err)
	}
}