use crate::{error::Truncated, Encode, Error};
use crate::tag::{Features, Version};
use crate::{
validate::Validate,
Error::{BufferTooSmall, CapabilityContainerTruncated},
};
#[cfg(any(feature = "std", feature = "alloc"))]
use alloc::vec::Vec;
#[repr(C)]
#[derive(Debug, Copy, Clone, Hash, derive_new::new)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "wasm", wasm_bindgen::prelude::wasm_bindgen)]
pub struct CapabilityContainer {
pub magic: u8,
pub version: Version,
pub size_blocks: u8,
pub features: Features,
}
impl CapabilityContainer {
#[inline(always)]
pub const fn size_ndef(&self) -> usize {
self.size_blocks as usize * 8
}
#[inline(always)]
pub const fn with_size_ndef(self, size: usize) -> Self {
Self {
magic: self.magic,
version: self.version,
size_blocks: (size / 8) as u8,
features: self.features,
}
}
#[inline(always)]
pub const fn with_size_blocks(self, size: u8) -> Self {
Self {
magic: self.magic,
version: self.version,
size_blocks: size,
features: self.features,
}
}
}
impl Validate for CapabilityContainer {
type Error = Error;
}
impl Encode for CapabilityContainer {
#[inline(always)]
fn encoded_len(&self) -> usize {
4
}
fn encode_into(&self, buf: &mut [u8]) -> Result<usize, Self::Error> {
let len = buf.len();
if len < 4 {
return Err(BufferTooSmall { got: len, want: 4 });
}
buf[0] = self.magic;
buf[1] = self.version.into();
buf[2] = self.size_blocks;
buf[3] = self.features.into();
Ok(4)
}
}
impl From<[u8; 4]> for CapabilityContainer {
#[inline(always)]
fn from(bytes: [u8; 4]) -> Self {
Self::new(bytes[0], bytes[1].into(), bytes[2], bytes[3].into())
}
}
impl From<CapabilityContainer> for [u8; 4] {
#[inline(always)]
fn from(cc: CapabilityContainer) -> Self {
[cc.magic, cc.version.into(), cc.size_blocks, cc.features.into()]
}
}
impl TryFrom<&[u8]> for CapabilityContainer {
type Error = Error;
fn try_from(bytes: &[u8]) -> Result<Self, Self::Error> {
let len = bytes.len();
if len < 4 {
return Err(CapabilityContainerTruncated(Truncated { got: len, want: 4 }));
}
Ok(Self::new(bytes[0], bytes[1].into(), bytes[2], bytes[3].into()))
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl TryFrom<&Vec<u8>> for CapabilityContainer {
type Error = Error;
#[inline(always)]
fn try_from(bytes: &Vec<u8>) -> Result<Self, Self::Error> {
Self::try_from(bytes.as_slice())
}
}
impl<const L: usize> TryFrom<&heapless::Vec<u8, L>> for CapabilityContainer {
type Error = Error;
#[inline(always)]
fn try_from(bytes: &heapless::Vec<u8, L>) -> Result<Self, Self::Error> {
Self::try_from(bytes.as_slice())
}
}