use std::{
fmt,
fmt::{Display, Formatter},
};
use super::MessageError;
pub use crate::proto::envelope::*;
#[macro_export]
macro_rules! wrap_in_envelope_body {
($($e:expr),+) => {{
use $crate::message::MessageExt;
let mut envelope_body = $crate::message::EnvelopeBody::new();
$(
envelope_body.push_part($e.to_encoded_bytes());
)*
envelope_body
}}
}
impl EnvelopeBody {
pub fn new() -> Self {
Self {
parts: Default::default(),
}
}
pub fn len(&self) -> usize {
self.parts.len()
}
pub fn total_size(&self) -> usize {
self.parts.iter().fold(0, |acc, b| acc + b.len())
}
pub fn is_empty(&self) -> bool {
self.parts.is_empty()
}
pub fn take_part(&mut self, index: usize) -> Option<Vec<u8>> {
Some(index)
.filter(|i| self.parts.len() > *i)
.map(|i| self.parts.remove(i))
}
pub fn push_part(&mut self, part: Vec<u8>) {
self.parts.push(part)
}
pub fn into_inner(self) -> Vec<Vec<u8>> {
self.parts
}
pub fn decode_part<T>(&self, index: usize) -> Result<Option<T>, MessageError>
where T: prost::Message + Default {
match self.parts.get(index) {
Some(part) => T::decode(part.as_slice()).map(Some).map_err(Into::into),
None => Ok(None),
}
}
}
impl Display for EnvelopeBody {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{} byte(s), {} part(s)", self.total_size(), self.len())
}
}