use core::borrow::{Borrow, BorrowMut};
use core::fmt::Debug;
use core::hash::Hash;
use core::ops::{Deref, DerefMut};
use crate::error::{Error, ErrorCode};
use crate::utils::init::{self, init, IntoFallibleInit};
use crate::utils::storage::Vec;
use super::{FromTLV, TLVElement, TLVTag, TLVWrite, ToTLV, TLV};
pub type OctetStr<'a> = Octets<'a>;
pub type OctetStrOwned<const N: usize> = OctetsOwned<N>;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(transparent)]
pub struct Octets<'a>(pub &'a [u8]);
impl<'a> Octets<'a> {
pub const fn new(slice: &'a [u8]) -> Self {
Self(slice)
}
}
impl Deref for Octets<'_> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
self.0
}
}
impl<'a> FromTLV<'a> for Octets<'a> {
fn from_tlv(element: &TLVElement<'a>) -> Result<Self, Error> {
Ok(Octets(element.str()?))
}
}
impl ToTLV for Octets<'_> {
fn to_tlv<W: TLVWrite>(&self, tag: &TLVTag, mut tw: W) -> Result<(), Error> {
tw.str(tag, self.0)
}
fn tlv_iter(&self, tag: TLVTag) -> impl Iterator<Item = Result<TLV<'_>, Error>> {
TLV::str(tag, self.0).into_tlv_iter()
}
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(transparent)]
pub struct OctetsOwned<const N: usize> {
pub vec: Vec<u8, N>,
}
impl<const N: usize> Default for OctetsOwned<N> {
fn default() -> Self {
Self::new()
}
}
impl<const N: usize> OctetsOwned<N> {
pub const fn new() -> Self {
Self {
vec: Vec::<u8, N>::new(),
}
}
pub fn init() -> impl init::Init<Self> {
init!(Self {
vec <- Vec::<u8, N>::init(),
})
}
}
impl<const N: usize> Borrow<[u8]> for OctetsOwned<N> {
fn borrow(&self) -> &[u8] {
&self.vec
}
}
impl<const N: usize> BorrowMut<[u8]> for OctetsOwned<N> {
fn borrow_mut(&mut self) -> &mut [u8] {
&mut self.vec
}
}
impl<const N: usize> Deref for OctetsOwned<N> {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.vec
}
}
impl<const N: usize> DerefMut for OctetsOwned<N> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.vec
}
}
impl<'a, const N: usize> FromTLV<'a> for OctetsOwned<N> {
fn from_tlv(element: &TLVElement<'a>) -> Result<Self, Error> {
Ok(Self {
vec: element
.str()?
.try_into()
.map_err(|_| ErrorCode::ConstraintError)?,
})
}
fn init_from_tlv(element: TLVElement<'a>) -> impl init::Init<Self, Error> {
init::Init::chain(OctetsOwned::init().into_fallible(), move |bytes| {
bytes
.vec
.extend_from_slice(element.str()?)
.map_err(|_| ErrorCode::ConstraintError)?;
Ok(())
})
}
}
impl<const N: usize> ToTLV for OctetsOwned<N> {
fn to_tlv<W: TLVWrite>(&self, tag: &TLVTag, mut tw: W) -> Result<(), Error> {
tw.str(tag, &self.vec)
}
fn tlv_iter(&self, tag: TLVTag) -> impl Iterator<Item = Result<TLV<'_>, Error>> {
TLV::str(tag, self.vec.as_slice()).into_tlv_iter()
}
}
#[cfg(feature = "alloc")]
#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
#[repr(transparent)]
pub struct OctetsVec {
pub vec: alloc::vec::Vec<u8>,
}
#[cfg(feature = "alloc")]
impl OctetsVec {
pub const fn new() -> Self {
Self {
vec: alloc::vec::Vec::new(),
}
}
pub const fn from_vec(vec: alloc::vec::Vec<u8>) -> Self {
Self { vec }
}
}
#[cfg(feature = "alloc")]
impl Borrow<[u8]> for OctetsVec {
fn borrow(&self) -> &[u8] {
&self.vec
}
}
#[cfg(feature = "alloc")]
impl BorrowMut<[u8]> for OctetsVec {
fn borrow_mut(&mut self) -> &mut [u8] {
&mut self.vec
}
}
#[cfg(feature = "alloc")]
impl Deref for OctetsVec {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.vec
}
}
#[cfg(feature = "alloc")]
impl DerefMut for OctetsVec {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.vec
}
}
#[cfg(feature = "alloc")]
impl<'a> FromTLV<'a> for OctetsVec {
fn from_tlv(element: &TLVElement<'a>) -> Result<Self, Error> {
Ok(Self {
vec: element.str()?.into(),
})
}
}
#[cfg(feature = "alloc")]
impl ToTLV for OctetsVec {
fn to_tlv<W: TLVWrite>(&self, tag: &TLVTag, mut tw: W) -> Result<(), Error> {
tw.str(tag, &self.vec)
}
fn tlv_iter(&self, tag: TLVTag) -> impl Iterator<Item = Result<TLV<'_>, Error>> {
TLV::str(tag, self.vec.as_slice()).into_tlv_iter()
}
}