use crate::{
compat::{
string::{String, ToString},
vec::Vec,
},
errcode::{Kind, Origin},
Address, Error, LocalMessage, Result, Route, TransportMessage,
};
use core::{
fmt::{self, Debug, Display, Formatter},
ops::{Deref, DerefMut},
};
use serde::{de::DeserializeOwned, Deserialize, Serialize};
pub type Encoded = Vec<u8>;
#[derive(Serialize, Deserialize, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
pub struct ProtocolId(String);
impl ProtocolId {
pub fn none() -> Self {
Self(String::new())
}
#[allow(clippy::should_implement_trait)]
pub fn from_str(s: &str) -> Self {
Self(s.to_string())
}
pub fn as_str(&self) -> &str {
self.0.as_str()
}
}
impl From<&'static str> for ProtocolId {
fn from(s: &'static str) -> Self {
Self::from_str(s)
}
}
impl Display for ProtocolId {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
pub trait Encodable {
fn encode(&self) -> Result<Encoded>;
}
pub trait Decodable: Sized {
#[allow(clippy::ptr_arg)]
fn decode(e: &[u8]) -> Result<Self>;
}
pub trait Message: Encodable + Decodable + Send + 'static {}
impl Message for () {}
impl Message for Vec<u8> {}
impl Message for String {}
impl<T> Encodable for T
where
T: Serialize,
{
fn encode(&self) -> Result<Encoded> {
Ok(serde_bare::to_vec(self)?)
}
}
impl<T> Decodable for T
where
T: DeserializeOwned,
{
fn decode(encoded: &[u8]) -> Result<Self> {
Ok(serde_bare::from_slice(encoded)?)
}
}
#[derive(Debug)]
pub struct NeutralMessage(Vec<u8>);
impl From<Vec<u8>> for NeutralMessage {
fn from(v: Vec<u8>) -> Self {
Self(v)
}
}
impl From<NeutralMessage> for Vec<u8> {
fn from(m: NeutralMessage) -> Self {
m.0
}
}
impl Encodable for NeutralMessage {
fn encode(&self) -> Result<Encoded> {
Ok(self.0.to_vec())
}
}
impl Decodable for NeutralMessage {
fn decode(v: &[u8]) -> Result<Self> {
Ok(Self(v.to_vec()))
}
}
impl Message for NeutralMessage {}
impl From<serde_bare::error::Error> for Error {
fn from(e: serde_bare::error::Error) -> Self {
Error::new(Origin::Core, Kind::Io, e)
}
}
impl From<minicbor::decode::Error> for Error {
fn from(e: minicbor::decode::Error) -> Self {
Error::new(Origin::Unknown, Kind::Invalid, e)
}
}
#[cfg(feature = "std")]
impl<E> From<minicbor::encode::Error<E>> for Error
where
E: std::error::Error + Send + Sync + 'static,
{
fn from(e: minicbor::encode::Error<E>) -> Self {
Error::new(Origin::Unknown, Kind::Invalid, e)
}
}
#[cfg(not(feature = "std"))]
impl<E: Display> From<minicbor::encode::Error<E>> for Error {
fn from(e: minicbor::encode::Error<E>) -> Self {
Error::new(Origin::Unknown, Kind::Invalid, e)
}
}
pub struct Routed<M: Message> {
inner: M,
msg_addr: Address,
local_msg: LocalMessage,
}
impl<M: Message> Routed<M> {
pub fn new(inner: M, msg_addr: Address, local_msg: LocalMessage) -> Self {
Self {
inner,
msg_addr,
local_msg,
}
}
#[doc(hidden)]
pub fn dissolve(&self) -> (Address, LocalMessage) {
(self.msg_addr.clone(), self.local_msg.clone())
}
#[inline]
pub fn msg_addr(&self) -> Address {
self.msg_addr.clone()
}
#[inline]
pub fn onward_route(&self) -> Route {
self.local_msg.transport().onward_route.clone()
}
#[inline]
pub fn return_route(&self) -> Route {
self.local_msg.transport().return_route.clone()
}
#[inline]
pub fn sender(&self) -> Address {
self.local_msg.transport().return_route.recipient()
}
#[inline]
pub fn body(self) -> M {
self.inner
}
#[inline]
pub fn as_body(&self) -> &M {
&self.inner
}
#[inline]
pub fn into_local_message(self) -> LocalMessage {
self.local_msg
}
#[inline]
pub fn into_transport_message(self) -> TransportMessage {
self.into_local_message().into_transport_message()
}
#[inline]
pub fn local_message(&self) -> &LocalMessage {
&self.local_msg
}
#[inline]
pub fn payload(&self) -> &[u8] {
&self.local_msg.transport().payload
}
#[inline]
pub fn take_payload(self) -> Vec<u8> {
self.local_msg.into_transport_message().payload
}
}
impl Routed<Any> {
pub fn cast<M: Message>(self) -> Result<Routed<M>> {
let inner = M::decode(&self.local_msg.transport().payload)?;
Ok(Routed {
inner,
msg_addr: self.msg_addr,
local_msg: self.local_msg,
})
}
}
impl<M: Message> Deref for Routed<M> {
type Target = M;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<M: Message> DerefMut for Routed<M> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}
impl<M: Message + PartialEq> PartialEq<M> for Routed<M> {
fn eq(&self, o: &M) -> bool {
&self.inner == o
}
}
impl<M: Message + Debug> Debug for Routed<M> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
impl<M: Message + Display> Display for Routed<M> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.inner.fmt(f)
}
}
#[derive(Clone, Debug, PartialEq, Eq, crate::Message)]
pub struct Any;
impl Display for Any {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "Any Message")
}
}
impl Encodable for Any {
fn encode(&self) -> Result<Encoded> {
Ok(vec![])
}
}
impl Decodable for Any {
fn decode(_: &[u8]) -> Result<Self> {
Ok(Self)
}
}