pub mod channel_data;
pub mod crypto;
pub mod message;
use self::{
channel_data::ChannelData,
message::{Message, attributes::AttributeType},
};
use std::{array::TryFromSliceError, ops::Range, str::Utf8Error};
#[derive(Debug)]
pub enum Error {
InvalidInput,
SummaryFailed,
NotFoundIntegrity,
IntegrityFailed,
NotFoundMagicNumber,
UnknownMethod,
FatalError,
Utf8Error(Utf8Error),
TryFromSliceError(TryFromSliceError),
}
impl std::error::Error for Error {}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
impl From<Utf8Error> for Error {
fn from(value: Utf8Error) -> Self {
Self::Utf8Error(value)
}
}
impl From<TryFromSliceError> for Error {
fn from(value: TryFromSliceError) -> Self {
Self::TryFromSliceError(value)
}
}
pub enum DecodeResult<'a> {
Message(Message<'a>),
ChannelData(ChannelData<'a>),
}
impl<'a> DecodeResult<'a> {
pub fn into_message(self) -> Option<Message<'a>> {
match self {
DecodeResult::Message(msg) => Some(msg),
_ => None,
}
}
pub fn into_channel_data(self) -> Option<ChannelData<'a>> {
match self {
DecodeResult::ChannelData(data) => Some(data),
_ => None,
}
}
}
#[derive(Debug, Clone)]
pub struct Attributes(Vec<(AttributeType, Range<usize>)>);
impl Default for Attributes {
fn default() -> Self {
Self(Vec::with_capacity(20))
}
}
impl Attributes {
pub fn append(&mut self, kind: AttributeType, range: Range<usize>) {
self.0.push((kind, range));
}
pub fn get(&self, kind: &AttributeType) -> Option<Range<usize>> {
self.0
.iter()
.find(|(k, _)| k == kind)
.map(|(_, v)| v.clone())
}
pub fn get_all<'a>(
&'a self,
kind: &'a AttributeType,
) -> impl Iterator<Item = &'a Range<usize>> {
self.0
.iter()
.filter(move |(k, _)| k == kind)
.map(|(_, v)| v)
}
pub fn clear(&mut self) {
if !self.0.is_empty() {
self.0.clear();
}
}
}
#[derive(Default)]
pub struct Decoder(Attributes);
impl Decoder {
pub fn decode<'a>(&'a mut self, bytes: &'a [u8]) -> Result<DecodeResult<'a>, Error> {
assert!(bytes.len() >= 4);
let flag = bytes[0] >> 6;
if flag > 3 {
return Err(Error::InvalidInput);
}
Ok(if flag == 0 {
self.0.clear();
DecodeResult::Message(Message::decode(bytes, &mut self.0)?)
} else {
DecodeResult::ChannelData(ChannelData::decode(bytes)?)
})
}
pub fn message_size(bytes: &[u8], is_tcp: bool) -> Result<usize, Error> {
let flag = bytes[0] >> 6;
if flag > 3 {
return Err(Error::InvalidInput);
}
Ok(if flag == 0 {
Message::message_size(bytes)?
} else {
ChannelData::message_size(bytes, is_tcp)?
})
}
}