use core::borrow::Borrow;
use core::fmt;
use core::mem::MaybeUninit;
use core::mem::transmute;
use core::ops::Deref;
use core::slice::from_raw_parts;
use super::{MAX_SIGNATURE, Signature, SignatureError, validate};
#[derive(Clone)]
pub struct SignatureBuf {
data: [MaybeUninit<u8>; MAX_SIGNATURE],
init: usize,
}
impl SignatureBuf {
pub const fn empty() -> Self {
Self {
data: unsafe { MaybeUninit::uninit().assume_init() },
init: 0,
}
}
pub const fn into_raw_parts(self) -> ([MaybeUninit<u8>; MAX_SIGNATURE], usize) {
(self.data, 0)
}
#[inline]
#[track_caller]
pub const fn new_const(signature: &[u8]) -> SignatureBuf {
if validate(signature).is_err() {
panic!("Invalid D-Bus signature")
};
unsafe { Self::from_slice_const_unchecked(signature) }
}
#[inline]
pub fn new(signature: &[u8]) -> Result<Self, SignatureError> {
validate(signature)?;
unsafe { Ok(Self::from_slice_unchecked(signature)) }
}
const unsafe fn from_slice_const_unchecked(bytes: &[u8]) -> Self {
debug_assert!(bytes.len() <= MAX_SIGNATURE);
let mut data = [0; MAX_SIGNATURE];
let mut n = 0;
while n < bytes.len() {
data[n] = bytes[n];
n += 1;
}
Self {
data: unsafe {
transmute::<[u8; MAX_SIGNATURE], [MaybeUninit<u8>; MAX_SIGNATURE]>(data)
},
init: bytes.len(),
}
}
#[inline]
pub(super) unsafe fn from_slice_unchecked(bytes: &[u8]) -> Self {
debug_assert!(bytes.len() <= MAX_SIGNATURE);
let mut this = Self::empty();
unsafe {
this.data
.as_mut_ptr()
.cast::<u8>()
.copy_from_nonoverlapping(bytes.as_ptr(), bytes.len());
}
this.init = bytes.len();
this
}
#[inline]
fn as_slice(&self) -> &[u8] {
unsafe { from_raw_parts(self.data.as_ptr().cast(), self.init) }
}
}
impl fmt::Display for SignatureBuf {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&**self, f)
}
}
impl fmt::Debug for SignatureBuf {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("SignatureBuf").field(&self.as_str()).finish()
}
}
impl Deref for SignatureBuf {
type Target = Signature;
fn deref(&self) -> &Self::Target {
unsafe { Signature::new_unchecked(self.as_slice()) }
}
}
impl Borrow<Signature> for SignatureBuf {
#[inline]
fn borrow(&self) -> &Signature {
self
}
}
impl AsRef<Signature> for SignatureBuf {
#[inline]
fn as_ref(&self) -> &Signature {
self
}
}
impl PartialEq<SignatureBuf> for SignatureBuf {
#[inline]
fn eq(&self, other: &SignatureBuf) -> bool {
self.as_slice() == other.as_slice()
}
}
impl Eq for SignatureBuf {}
impl PartialEq<str> for SignatureBuf {
#[inline]
fn eq(&self, other: &str) -> bool {
self.as_bytes() == other.as_bytes()
}
}
impl PartialEq<&str> for SignatureBuf {
#[inline]
fn eq(&self, other: &&str) -> bool {
self.as_bytes() == other.as_bytes()
}
}
impl PartialEq<Signature> for SignatureBuf {
#[inline]
fn eq(&self, other: &Signature) -> bool {
self.as_slice() == other.as_bytes()
}
}
impl PartialEq<&Signature> for SignatureBuf {
#[inline]
fn eq(&self, other: &&Signature) -> bool {
self.as_slice() == other.as_bytes()
}
}