use std::collections::BTreeMap;
use std::vec::Vec;
use crate::error::*;
use crate::frame_codec::*;
use crate::symbol::*;
use crate::types::*;
pub trait TryFromValue: std::fmt::Debug {
fn try_from(value: Value) -> Result<Self>
where
Self: std::marker::Sized;
}
pub trait TryFromValueVec: TryFromValue {}
impl<T: TryFromValue> TryFromValue for Option<T> {
fn try_from(value: Value) -> Result<Self> {
match value {
Value::Null => Ok(None),
_ => Ok(Some(T::try_from(value)?)),
}
}
}
impl TryFromValue for Vec<u8> {
fn try_from(value: Value) -> Result<Self> {
match value {
Value::Binary(v) => Ok(v),
v => Err(AmqpError::decode_error(Some(
format!("Error converting value to u8: {:?}", v).as_str(),
))),
}
}
}
impl<T: TryFromValueVec> TryFromValue for Vec<T> {
fn try_from(value: Value) -> Result<Self> {
match value {
Value::List(v) | Value::Array(v) => {
Ok(v.into_iter().map(T::try_from).collect::<Result<Vec<T>>>()?)
}
_ => Ok(vec![T::try_from(value)?]),
}
}
}
impl TryFromValue for u8 {
fn try_from(value: Value) -> Result<Self> {
match value {
Value::Ubyte(v) => Ok(v),
v => Err(AmqpError::decode_error(Some(
format!("Error converting value to u8: {:?}", v).as_str(),
))),
}
}
}
impl TryFromValue for u64 {
fn try_from(value: Value) -> Result<Self> {
match value {
Value::Ulong(v) => Ok(v),
_ => Err(AmqpError::decode_error(Some(
"Error converting value to u64",
))),
}
}
}
impl TryFromValue for u32 {
fn try_from(value: Value) -> Result<Self> {
match value {
Value::Uint(v) => Ok(v),
_ => Err(AmqpError::decode_error(Some(
"Error converting value to u32",
))),
}
}
}
impl TryFromValue for u16 {
fn try_from(value: Value) -> Result<Self> {
match value {
Value::Ushort(v) => Ok(v),
_ => Err(AmqpError::decode_error(Some(
"Error converting value to u32",
))),
}
}
}
impl TryFromValue for bool {
fn try_from(value: Value) -> Result<Self> {
match value {
Value::Bool(v) => Ok(v),
_ => Err(AmqpError::decode_error(Some(
"Error converting value to bool",
))),
}
}
}
impl TryFromValueVec for String {}
impl TryFromValue for String {
fn try_from(value: Value) -> Result<Self> {
match value {
Value::Symbol(v) => Ok(String::from_utf8_lossy(&v[..]).to_string()),
Value::String(v) => Ok(v),
_ => Err(AmqpError::decode_error(Some(
"Error converting value to String",
))),
}
}
}
impl<T: TryFromValue + std::cmp::Ord> TryFromValue for BTreeMap<T, Value> {
fn try_from(value: Value) -> Result<Self> {
match value {
Value::Map(v) => {
let mut m = BTreeMap::new();
for (key, value) in v.into_iter() {
m.insert(T::try_from(key)?, value);
}
Ok(m)
}
_ => Err(AmqpError::decode_error(Some(
"Error converting value to Map<T, Value>",
))),
}
}
}
impl TryFromValue for Timestamp {
fn try_from(value: Value) -> Result<Self>
where
Self: Sized,
{
match value {
Value::Timestamp(v) => Ok(Timestamp(v)),
_ => Err(AmqpError::decode_error(Some(
"Error converting value to Timestamp",
))),
}
}
}
impl TryFromValue for Value {
fn try_from(value: Value) -> Result<Self> {
Ok(value)
}
}
impl TryFromValueVec for Symbol {}
impl TryFromValue for Symbol {
fn try_from(value: Value) -> Result<Self> {
match value {
Value::Symbol(v) => Ok(Symbol::from(v)),
_ => Err(AmqpError::decode_error(Some(
"Error converting value to Symbol",
))),
}
}
}
impl TryFromValue for ErrorCondition {
fn try_from(value: Value) -> Result<Self> {
if let Value::Described(descriptor, mut list) = value {
let decoder = FrameDecoder::new(&descriptor, &mut list)?;
match *descriptor {
DESC_ERROR => ErrorCondition::decode(decoder),
_ => Err(AmqpError::decode_error(Some(
format!("Expected error descriptor but found {:?}", *descriptor).as_str(),
))),
}
} else {
Err(AmqpError::decode_error(Some(
"Missing expected error descriptor",
)))
}
}
}