use crate::errors::ByteArrayError;
use crate::model::ByteArray;
use alloc::vec;
use alloc::vec::Vec;
use core::str::FromStr;
impl<const N: usize> From<&[u8; N]> for ByteArray {
fn from(value: &[u8; N]) -> Self {
ByteArray::from(&value[..])
}
}
impl From<&[u8]> for ByteArray {
fn from(value: &[u8]) -> Self {
ByteArray {
bytes: value.to_vec(),
}
}
}
impl From<Vec<u8>> for ByteArray {
fn from(bytes: Vec<u8>) -> Self {
ByteArray {
bytes, }
}
}
impl From<u8> for ByteArray {
fn from(value: u8) -> Self {
ByteArray { bytes: vec![value] }
}
}
impl FromStr for ByteArray {
type Err = ByteArrayError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
if s.is_empty() {
return Err(ByteArrayError::EmptyInput);
}
if s.starts_with("0x") || s.starts_with("0X") {
return ByteArray::from_hex(&s[2..]);
}
if s.starts_with("0b") || s.starts_with("0B") {
return ByteArray::from_bin(&s[2..]);
}
if s.starts_with("0o") || s.starts_with("0O") {
unimplemented!()
}
Ok(ByteArray::from(s.as_bytes()))
}
}
impl<const N: usize> From<[u8; N]> for ByteArray {
fn from(value: [u8; N]) -> Self {
(&value).into()
}
}
impl ByteArray {
#[allow(unsafe_code)]
pub unsafe fn as_ptr(&self) -> *const u8 {
self.bytes.as_ptr()
}
#[allow(unsafe_code)]
pub unsafe fn as_mut_ptr(&mut self) -> *mut u8 {
self.bytes.as_mut_ptr()
}
}
#[cfg(test)]
#[allow(unsafe_code)]
mod unsafe_tests {
use crate::try_hex;
#[test]
fn test_unsafe_ptr() {
let data = try_hex!("00fe0abcd0abcdfeab").unwrap();
unsafe {
assert_eq!(*data.as_ptr().add(1), 0xfe);
assert_eq!(*data.as_ptr().add(7), 0xfe);
}
}
#[test]
fn test_unsafe_mut_ptr() {
let mut data = try_hex!("cafebeef").unwrap();
unsafe {
*data.as_mut_ptr().add(3) = 0xed;
}
assert_eq!(*data.get(3).unwrap(), 0xed);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_from_slice_reference() {
let bytes = [0xde, 0xad, 0xbe, 0xef];
let bytes_slice = &bytes;
let byte_array: ByteArray = bytes_slice.into();
assert_eq!(byte_array.as_bytes(), [0xde, 0xad, 0xbe, 0xef]);
}
#[test]
fn test_from_vec() {
let bytes: Vec<u8> = vec![0xde, 0xad, 0xbe, 0xef];
let arr = ByteArray::from(bytes);
assert_eq!(arr.as_bytes(), &[0xde, 0xad, 0xbe, 0xef]);
}
#[test]
fn test_from_single_byte() {
let arr: ByteArray = 0xff.into();
assert_eq!(arr.as_bytes(), [0xff]);
}
#[test]
fn test_from_array_literal() {
let arr: ByteArray = [0xaa, 0xbb, 0xcc].into();
assert_eq!(arr.as_bytes(), [0xaa, 0xbb, 0xcc]);
}
#[test]
fn test_from_array_reference() {
let bytes = [0x01, 0x02, 0x03, 0x04];
let arr: ByteArray = (&bytes).into();
assert_eq!(arr.as_bytes(), [0x01, 0x02, 0x03, 0x04]);
}
#[test]
fn test_from_empty_slice() {
let empty: &[u8] = &[];
let arr: ByteArray = empty.into();
assert!(arr.is_empty());
}
#[test]
fn test_from_empty_vec() {
let empty: Vec<u8> = Vec::new();
let arr = ByteArray::from(empty);
assert!(arr.is_empty());
}
#[test]
fn test_from_str_hex() {
let arr: ByteArray = "0xdeadbeef".parse().unwrap();
assert_eq!(arr.as_bytes(), [0xde, 0xad, 0xbe, 0xef]);
}
#[test]
fn test_from_str_hex_uppercase() {
let arr: ByteArray = "0XDEADBEEF".parse().unwrap();
assert_eq!(arr.as_bytes(), [0xde, 0xad, 0xbe, 0xef]);
}
#[test]
fn test_from_str_hex_mixed_case() {
let arr: ByteArray = "0xDeAdBeEf".parse().unwrap();
assert_eq!(arr.as_bytes(), [0xde, 0xad, 0xbe, 0xef]);
}
#[test]
fn test_from_str_hex_odd_length() {
let arr: ByteArray = "0xfff".parse().unwrap();
assert_eq!(arr.as_bytes(), [0x0f, 0xff]);
}
#[test]
fn test_from_str_binary() {
let arr: ByteArray = "0b11011110".parse().unwrap();
assert_eq!(arr.as_bytes(), [0xde]);
}
#[test]
fn test_from_str_binary_uppercase() {
let arr: ByteArray = "0B11011110".parse().unwrap();
assert_eq!(arr.as_bytes(), [0xde]);
}
#[test]
fn test_from_str_utf8() {
let arr: ByteArray = "hello".parse().unwrap();
assert_eq!(arr.as_bytes(), b"hello");
}
#[test]
fn test_from_str_utf8_single_char() {
let arr: ByteArray = "A".parse().unwrap();
assert_eq!(arr.as_bytes(), b"A");
}
#[test]
fn test_from_str_empty_error() {
let result: Result<ByteArray, ByteArrayError> = "".parse();
assert!(result.is_err());
if let Err(e) = result {
assert!(matches!(e, ByteArrayError::EmptyInput));
}
}
#[test]
fn test_from_str_hex_invalid_char() {
let result: Result<ByteArray, ByteArrayError> = "0xgggg".parse();
assert!(result.is_err());
}
#[test]
fn test_from_str_binary_invalid_char() {
let result: Result<ByteArray, ByteArrayError> = "0b12345".parse();
assert!(result.is_err());
}
#[test]
fn test_from_large_array() {
let large: Vec<u8> = (0..1000).map(|i| (i % 256) as u8).collect();
let arr = ByteArray::from(large.clone());
assert_eq!(arr.len(), 1000);
assert_eq!(arr.as_bytes(), large.as_slice());
}
}