use std::collections::BTreeMap;
use std::error::Error;
use std::fmt::{self, Display, Formatter};
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum ClientError {
AccessDenied,
NoSuchAccount,
AccountExists,
NoSuchData,
DataExists,
DataTooLarge,
NoSuchEntry,
TooManyEntries,
InvalidEntryActions(BTreeMap<Vec<u8>, EntryError>),
NoSuchKey,
InvalidOwners,
InvalidSuccessor(u64),
InvalidOperation,
InvalidInvitation,
InvitationAlreadyClaimed,
LowBalance,
NetworkFull,
NetworkOther(String),
}
impl<T: Into<String>> From<T> for ClientError {
fn from(err: T) -> Self {
ClientError::NetworkOther(err.into())
}
}
impl Display for ClientError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match *self {
ClientError::AccessDenied => write!(f, "Access denied"),
ClientError::NoSuchAccount => write!(f, "Account does not exist for client"),
ClientError::AccountExists => write!(f, "Account already exists for client"),
ClientError::NoSuchData => write!(f, "Requested data not found"),
ClientError::DataExists => write!(f, "Data given already exists"),
ClientError::DataTooLarge => write!(f, "Data given is too large"),
ClientError::NoSuchEntry => write!(f, "Requested entry not found"),
ClientError::TooManyEntries => write!(f, "Exceeded a limit on a number of entries"),
ClientError::InvalidEntryActions(ref errors) => {
write!(f, "Entry actions are invalid: {:?}", errors)
}
ClientError::NoSuchKey => write!(f, "Key does not exists"),
ClientError::InvalidOwners => write!(f, "The list of owner keys is invalid"),
ClientError::InvalidOperation => write!(f, "Requested operation is not allowed"),
ClientError::InvalidInvitation => write!(f, "Invitation token not found"),
ClientError::InvitationAlreadyClaimed => {
write!(f, "Invitation token has already been used")
}
ClientError::InvalidSuccessor(_) => {
write!(f, "Data given is not a valid successor of stored data")
}
ClientError::LowBalance => write!(f, "Insufficient account balance for this operation"),
ClientError::NetworkFull => write!(f, "Network cannot store any further data"),
ClientError::NetworkOther(ref error) => write!(f, "Error on Vault network: {}", error),
}
}
}
impl Error for ClientError {
fn description(&self) -> &str {
match *self {
ClientError::AccessDenied => "Access denied",
ClientError::NoSuchAccount => "No such account",
ClientError::AccountExists => "Account exists",
ClientError::NoSuchData => "No such data",
ClientError::DataExists => "Data exists",
ClientError::DataTooLarge => "Data is too large",
ClientError::NoSuchEntry => "No such entry",
ClientError::TooManyEntries => "Too many entries",
ClientError::InvalidEntryActions(_) => "Invalid entry actions",
ClientError::NoSuchKey => "No such key",
ClientError::InvalidOwners => "Invalid owners",
ClientError::InvalidSuccessor(_) => "Invalid data successor",
ClientError::InvalidOperation => "Invalid operation",
ClientError::InvalidInvitation => "Invalid invitation token",
ClientError::InvitationAlreadyClaimed => "Invitation token already claimed",
ClientError::LowBalance => "Low account balance",
ClientError::NetworkFull => "Network full",
ClientError::NetworkOther(ref error) => error,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum EntryError {
NoSuchEntry,
EntryExists(u64),
InvalidSuccessor(u64),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn conversion_from_str_literal() {
fn mutate() -> Result<(), ClientError> {
Err("Mutation")?
}
let err_get = ClientError::from("Get");
let err_mutation = unwrap_err!(mutate());
match (err_get, err_mutation) {
(ClientError::NetworkOther(val0), ClientError::NetworkOther(val1)) => {
assert_eq!(&val0, "Get");
assert_eq!(&val1, "Mutation");
}
err => panic!("Unexpected conversion: {:?}", err),
}
}
}