use crate::{
errors::ErrorDebug, AData, ADataEntries, ADataEntry, ADataIndices, ADataOwner,
ADataPermissions, ADataPubPermissionSet, ADataUnpubPermissionSet, AppPermissions, Coins, Error,
IData, MData, MDataEntries, MDataPermissionSet, MDataValue, MDataValues, PublicKey, Result,
Signature, Transaction,
};
use serde::{Deserialize, Serialize};
use std::{
collections::{BTreeMap, BTreeSet},
convert::TryFrom,
fmt,
};
#[allow(clippy::large_enum_variant, clippy::type_complexity)]
#[derive(Hash, Eq, PartialEq, PartialOrd, Ord, Clone, Serialize, Deserialize)]
pub enum Response {
GetIData(Result<IData>),
GetMData(Result<MData>),
GetMDataShell(Result<MData>),
GetMDataVersion(Result<u64>),
ListMDataEntries(Result<MDataEntries>),
ListMDataKeys(Result<BTreeSet<Vec<u8>>>),
ListMDataValues(Result<MDataValues>),
ListMDataUserPermissions(Result<MDataPermissionSet>),
ListMDataPermissions(Result<BTreeMap<PublicKey, MDataPermissionSet>>),
GetMDataValue(Result<MDataValue>),
GetAData(Result<AData>),
GetADataShell(Result<AData>),
GetADataOwners(Result<ADataOwner>),
GetADataRange(Result<ADataEntries>),
GetADataValue(Result<Vec<u8>>),
GetADataIndices(Result<ADataIndices>),
GetADataLastEntry(Result<ADataEntry>),
GetADataPermissions(Result<ADataPermissions>),
GetPubADataUserPermissions(Result<ADataPubPermissionSet>),
GetUnpubADataUserPermissions(Result<ADataUnpubPermissionSet>),
GetBalance(Result<Coins>),
Transaction(Result<Transaction>),
GetLoginPacket(Result<(Vec<u8>, Signature)>),
ListAuthKeysAndVersion(Result<(BTreeMap<PublicKey, AppPermissions>, u64)>),
Mutation(Result<()>),
}
#[derive(Debug, PartialEq)]
pub enum TryFromError {
WrongType,
Response(Error),
}
macro_rules! try_from {
($ok_type:ty, $($variant:ident),*) => {
impl TryFrom<Response> for $ok_type {
type Error = TryFromError;
fn try_from(response: Response) -> std::result::Result<Self, Self::Error> {
match response {
$(
Response::$variant(Ok(data)) => Ok(data),
Response::$variant(Err(error)) => Err(TryFromError::Response(error)),
)*
_ => Err(TryFromError::WrongType),
}
}
}
};
}
try_from!(IData, GetIData);
try_from!(MData, GetMData, GetMDataShell);
try_from!(u64, GetMDataVersion);
try_from!(MDataEntries, ListMDataEntries);
try_from!(BTreeSet<Vec<u8>>, ListMDataKeys);
try_from!(MDataValues, ListMDataValues);
try_from!(MDataPermissionSet, ListMDataUserPermissions);
try_from!(BTreeMap<PublicKey, MDataPermissionSet>, ListMDataPermissions);
try_from!(MDataValue, GetMDataValue);
try_from!(Vec<u8>, GetADataValue);
try_from!(AData, GetAData, GetADataShell);
try_from!(ADataOwner, GetADataOwners);
try_from!(ADataEntries, GetADataRange);
try_from!(ADataIndices, GetADataIndices);
try_from!(ADataEntry, GetADataLastEntry);
try_from!(ADataPermissions, GetADataPermissions);
try_from!(ADataPubPermissionSet, GetPubADataUserPermissions);
try_from!(ADataUnpubPermissionSet, GetUnpubADataUserPermissions);
try_from!(Coins, GetBalance);
try_from!(Transaction, Transaction);
try_from!(
(BTreeMap<PublicKey, AppPermissions>, u64),
ListAuthKeysAndVersion
);
try_from!((Vec<u8>, Signature), GetLoginPacket);
try_from!((), Mutation);
impl fmt::Debug for Response {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use Response::*;
match self {
GetIData(res) => write!(f, "Response::GetIData({:?})", ErrorDebug(res)),
GetMData(res) => write!(f, "Response::GetMData({:?})", ErrorDebug(res)),
GetMDataShell(res) => write!(f, "Response::GetMDataShell({:?})", ErrorDebug(res)),
GetMDataVersion(res) => write!(f, "Response::GetMDataVersion({:?})", ErrorDebug(res)),
ListMDataEntries(res) => write!(f, "Response::ListMDataEntries({:?})", ErrorDebug(res)),
ListMDataKeys(res) => write!(f, "Response::ListMDataKeys({:?})", ErrorDebug(res)),
ListMDataValues(res) => write!(f, "Response::ListMDataValues({:?})", ErrorDebug(res)),
ListMDataPermissions(res) => {
write!(f, "Response::ListMDataPermissions({:?})", ErrorDebug(res))
}
ListMDataUserPermissions(res) => write!(
f,
"Response::ListMDataUserPermissions({:?})",
ErrorDebug(res)
),
GetMDataValue(res) => write!(f, "Response::GetMDataValue({:?})", ErrorDebug(res)),
GetAData(res) => write!(f, "Response::GetAData({:?})", ErrorDebug(res)),
GetADataValue(res) => write!(f, "Response::GetADataValue({:?})", ErrorDebug(res)),
GetADataRange(res) => write!(f, "Response::GetADataRange({:?})", ErrorDebug(res)),
GetADataIndices(res) => write!(f, "Response::GetADataIndices({:?})", ErrorDebug(res)),
GetADataLastEntry(res) => {
write!(f, "Response::GetADataLastEntry({:?})", ErrorDebug(res))
}
GetADataPermissions(res) => {
write!(f, "Response::GetADataPermissions({:?})", ErrorDebug(res))
}
GetPubADataUserPermissions(res) => write!(
f,
"Response::GetPubADataUserPermissions({:?})",
ErrorDebug(res)
),
GetUnpubADataUserPermissions(res) => write!(
f,
"Response::GetUnpubADataUserPermissions({:?})",
ErrorDebug(res)
),
GetADataShell(res) => write!(f, "Response::GetADataShell({:?})", ErrorDebug(res)),
GetADataOwners(res) => write!(f, "Response::GetADataOwners({:?})", ErrorDebug(res)),
GetBalance(res) => write!(f, "Response::GetBalance({:?})", ErrorDebug(res)),
Transaction(res) => write!(f, "Response::Transaction({:?})", ErrorDebug(res)),
GetLoginPacket(res) => write!(f, "Response::GetLoginPacket({:?})", ErrorDebug(res)),
ListAuthKeysAndVersion(res) => {
write!(f, "Response::ListAuthKeysAndVersion({:?})", ErrorDebug(res))
}
Mutation(res) => write!(f, "Response::Mutation({:?})", ErrorDebug(res)),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{PubImmutableData, UnseqMutableData};
use std::convert::{TryFrom, TryInto};
use unwrap::{unwrap, unwrap_err};
#[test]
fn debug_format() {
let response = Response::Mutation(Ok(()));
assert_eq!(format!("{:?}", response), "Response::Mutation(Success)");
use crate::Error;
let errored_response = Response::GetADataShell(Err(Error::AccessDenied));
assert_eq!(
format!("{:?}", errored_response),
"Response::GetADataShell(AccessDenied)"
);
}
#[test]
fn try_from() {
use Response::*;
let i_data = IData::Pub(PubImmutableData::new(vec![1, 3, 1, 4]));
let e = Error::AccessDenied;
assert_eq!(i_data, unwrap!(GetIData(Ok(i_data.clone())).try_into()));
assert_eq!(
TryFromError::Response(e.clone()),
unwrap_err!(IData::try_from(GetIData(Err(e.clone()))))
);
assert_eq!(
TryFromError::WrongType,
unwrap_err!(IData::try_from(Mutation(Ok(()))))
);
let mut data = BTreeMap::new();
let _ = data.insert(vec![1], vec![10]);
let owners = PublicKey::Bls(threshold_crypto::SecretKey::random().public_key());
let m_data = MData::Unseq(UnseqMutableData::new_with_data(
*i_data.name(),
1,
data,
BTreeMap::new(),
owners,
));
assert_eq!(m_data, unwrap!(GetMData(Ok(m_data.clone())).try_into()));
assert_eq!(
TryFromError::Response(e.clone()),
unwrap_err!(MData::try_from(GetMData(Err(e))))
);
assert_eq!(
TryFromError::WrongType,
unwrap_err!(MData::try_from(Mutation(Ok(()))))
);
}
}