#[cfg(feature = "alloc")]
use std_alloc::string::{FromUtf8Error, String};
use toad_array::Array;
use toad_msg::{Id, Message, Payload, TryIntoBytes, Type};
use crate::platform::{self, PlatformTypes};
use crate::req::Req;
pub mod code;
pub struct Resp<P>(platform::Message<P>) where P: PlatformTypes;
impl<P> AsRef<platform::Message<P>> for Resp<P> where P: PlatformTypes
{
fn as_ref(&self) -> &platform::Message<P> {
&self.0
}
}
impl<P> AsMut<platform::Message<P>> for Resp<P> where P: PlatformTypes
{
fn as_mut(&mut self) -> &mut platform::Message<P> {
&mut self.0
}
}
impl<P> core::fmt::Debug for Resp<P> where P: PlatformTypes
{
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_tuple("Resp").field(&self.0).finish()
}
}
impl<P> Clone for Resp<P> where P: PlatformTypes
{
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<P> PartialEq for Resp<P> where P: PlatformTypes
{
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<P: PlatformTypes> Resp<P> {
pub fn msg(&self) -> &platform::Message<P> {
&self.0
}
pub fn msg_mut(&mut self) -> &mut platform::Message<P> {
&mut self.0
}
pub fn for_request(req: &Req<P>) -> Option<Self> {
match req.msg_type() {
| Type::Con => Some(Self::ack(req)),
| Type::Non => Some(Self::non(req)),
| _ => None,
}
}
pub fn ack(req: &Req<P>) -> Self {
let msg = Message { ty: Type::Ack,
id: req.msg().id,
opts: P::MessageOptions::default(),
code: code::CONTENT,
ver: Default::default(),
payload: Payload(Default::default()),
token: req.msg().token };
Self(msg)
}
pub fn con(req: &Req<P>) -> Self {
let msg = Message { ty: Type::Con,
id: Id(Default::default()),
opts: P::MessageOptions::default(),
code: code::CONTENT,
ver: Default::default(),
payload: Payload(Default::default()),
token: req.msg().token };
Self(msg)
}
pub fn non(req: &Req<P>) -> Self {
let msg = Message { ty: Type::Non,
id: Id(Default::default()),
opts: P::MessageOptions::default(),
code: code::CONTENT,
ver: Default::default(),
payload: Payload(Default::default()),
token: req.msg().token };
Self(msg)
}
pub fn payload(&self) -> impl Iterator<Item = &u8> {
self.0.payload.0.iter()
}
pub fn msg_type(&self) -> toad_msg::Type {
self.0.ty
}
pub fn msg_id(&self) -> toad_msg::Id {
self.0.id
}
pub fn token(&self) -> toad_msg::Token {
self.0.token
}
#[cfg(feature = "alloc")]
pub fn payload_string(&self) -> Result<String, FromUtf8Error> {
String::from_utf8(self.payload().copied().collect())
}
pub fn code(&self) -> toad_msg::Code {
self.0.code
}
pub fn set_code(&mut self, code: toad_msg::Code) {
self.0.code = code;
}
pub fn set_payload<Bytes: IntoIterator<Item = u8>>(&mut self, payload: Bytes) {
self.0.payload = Payload(payload.into_iter().collect());
}
}
impl<P: PlatformTypes> From<Resp<P>> for platform::Message<P> {
fn from(rep: Resp<P>) -> Self {
rep.0
}
}
impl<P: PlatformTypes> From<platform::Message<P>> for Resp<P> {
fn from(msg: platform::Message<P>) -> Self {
Self(msg)
}
}
impl<P: PlatformTypes> TryIntoBytes for Resp<P> {
type Error = <platform::Message<P> as TryIntoBytes>::Error;
fn try_into_bytes<C: Array<Item = u8>>(self) -> Result<C, Self::Error> {
platform::Message::<P>::from(self).try_into_bytes()
}
}