use core::fmt::{self, Display};
use bitflags::bitflags;
use le_stream::{FromLeStream, ToLeStream};
pub use self::callback_type::CallbackType;
mod callback_type;
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq, FromLeStream, ToLeStream)]
pub struct Response(u8);
bitflags! {
impl Response: u8 {
const IS_RESPONSE = 0b1000_0000;
const NETWORK_INDEX_1 = 0b0100_0000;
const NETWORK_INDEX_0 = 0b0010_0000;
const CALLBACK_TYPE_1 = 0b0001_0000;
const CALLBACK_TYPE_0 = 0b0000_1000;
const CALLBACK_PENDING = 0b0000_0100;
const TRUNCATED = 0b0000_0010;
const OVERFLOW = 0b0000_0001;
}
}
impl Response {
#[must_use]
pub const fn is_response(self) -> bool {
self.contains(Self::IS_RESPONSE)
}
#[must_use]
pub fn network_index(self) -> u8 {
(self.bits() & (Self::NETWORK_INDEX_1 | Self::NETWORK_INDEX_0).bits()) >> 5
}
#[must_use]
pub const fn callback_type(self) -> Option<CallbackType> {
match (
self.contains(Self::CALLBACK_TYPE_1),
self.contains(Self::CALLBACK_TYPE_0),
) {
(true, true) => Some(CallbackType::Reserved),
(true, false) => Some(CallbackType::Async),
(false, true) => Some(CallbackType::Sync),
(false, false) => None,
}
}
#[must_use]
pub const fn is_callback_pending(self) -> bool {
self.contains(Self::CALLBACK_PENDING)
}
#[must_use]
pub const fn is_truncated(self) -> bool {
self.contains(Self::TRUNCATED)
}
#[must_use]
pub const fn has_overflowed(self) -> bool {
self.contains(Self::OVERFLOW)
}
}
impl Display for Response {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Response {{ is_response: {}, network_index: {}, callback_type: {}, is_callback_pending: {}, is_truncated: {}, has_overflowed: {} }}",
self.is_response(),
self.network_index(),
self.callback_type()
.map_or("Not a callback", CallbackType::as_str),
self.is_callback_pending(),
self.is_truncated(),
self.has_overflowed()
)
}
}