use crate::{
compat::{
string::{String, ToString},
vec::Vec,
},
errcode::{Kind, Origin},
Address, Error, LocalMessage, Result, Route,
};
use core::fmt::{self, Debug, Display, Formatter};
use core::marker::PhantomData;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use serde_bare::ser::{Serializer, VecWrite};
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 String {}
impl Message for Vec<u8> {}
impl Encodable for Vec<u8> {
fn encode(self) -> Result<Encoded> {
Ok(self)
}
}
impl Decodable for Vec<u8> {
fn decode(e: &[u8]) -> Result<Self> {
Ok(e.to_vec())
}
}
impl Encodable for () {
fn encode(self) -> Result<Encoded> {
Ok(vec![])
}
}
impl Decodable for () {
fn decode(_e: &[u8]) -> Result<Self> {
Ok(())
}
}
impl Encodable for String {
fn encode(self) -> Result<Encoded> {
serialize(self)
}
}
impl Decodable for String {
fn decode(e: &[u8]) -> Result<Self> {
deserialize(e)
}
}
pub fn serialize<T: Serialize>(t: T) -> Result<Encoded> {
let mut vec = Vec::new();
let mut serializer = Serializer::new(VecWrite::new(&mut vec));
t.serialize(&mut serializer)?;
Ok(vec)
}
pub fn deserialize<T: DeserializeOwned>(encoded: &[u8]) -> Result<T> {
Ok(serde_bare::from_slice(encoded)?)
}
#[derive(Debug, Clone)]
pub struct NeutralMessage(Vec<u8>);
impl NeutralMessage {
pub fn into_vec(self) -> Vec<u8> {
self.0
}
}
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)
}
}
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 {
#[track_caller]
fn from(e: serde_bare::error::Error) -> Self {
Error::new(Origin::Core, Kind::Io, e)
}
}
impl From<minicbor::decode::Error> for Error {
#[track_caller]
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,
{
#[track_caller]
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 {
#[track_caller]
fn from(e: minicbor::encode::Error<E>) -> Self {
Error::new(Origin::Unknown, Kind::Invalid, e)
}
}
pub struct Routed<M: Message> {
phantom: PhantomData<M>,
msg_addr: Address,
src_addr: Address,
local_msg: LocalMessage,
}
impl<M: Message> Routed<M> {
pub fn new(msg_addr: Address, src_addr: Address, local_msg: LocalMessage) -> Self {
Self {
phantom: PhantomData,
msg_addr,
src_addr,
local_msg,
}
}
#[inline]
pub fn msg_addr(&self) -> &Address {
&self.msg_addr
}
#[inline]
pub fn src_addr(&self) -> &Address {
&self.src_addr
}
#[inline]
pub fn onward_route(&self) -> &Route {
self.local_msg.onward_route()
}
#[inline]
pub fn return_route(&self) -> &Route {
self.local_msg.return_route()
}
#[inline]
pub fn sender(&self) -> Result<&Address> {
self.local_msg.return_route().recipient()
}
#[inline]
pub fn into_body(self) -> Result<M> {
M::decode(&self.into_payload())
}
#[inline]
pub fn into_local_message(self) -> LocalMessage {
self.local_msg
}
#[inline]
pub fn local_message(&self) -> &LocalMessage {
&self.local_msg
}
#[inline]
pub fn payload(&self) -> &[u8] {
self.local_msg.payload()
}
#[inline]
pub fn into_payload(self) -> Vec<u8> {
self.local_msg.into_payload()
}
}
impl<M: Message + Debug> Debug for Routed<M> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_struct("Routed")
.field("msg_addr", &self.msg_addr)
.field("src_addr", &self.src_addr)
.field("type", &core::any::type_name::<M>())
.field("local_msg", &self.local_msg)
.finish()
}
}
#[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)
}
}