use crate::ule::*;
unsafe impl<T: ULE, const N: usize> ULE for [T; N] {
#[inline]
fn validate_bytes(bytes: &[u8]) -> Result<(), UleError> {
if N == 0 {
return Err(UleError::length::<Self>(bytes.len()));
}
if bytes.len() % size_of::<Self>() != 0 {
return Err(UleError::length::<Self>(bytes.len()));
}
T::validate_bytes(bytes)
}
}
impl<T: AsULE, const N: usize> AsULE for [T; N] {
type ULE = [T::ULE; N];
#[inline]
fn to_unaligned(self) -> Self::ULE {
self.map(T::to_unaligned)
}
#[inline]
fn from_unaligned(unaligned: Self::ULE) -> Self {
unaligned.map(T::from_unaligned)
}
}
unsafe impl<T: EqULE, const N: usize> EqULE for [T; N] {}
unsafe impl VarULE for str {
#[inline]
fn validate_bytes(bytes: &[u8]) -> Result<(), UleError> {
core::str::from_utf8(bytes).map_err(|_| UleError::parse::<Self>())?;
Ok(())
}
#[inline]
fn parse_bytes(bytes: &[u8]) -> Result<&Self, UleError> {
core::str::from_utf8(bytes).map_err(|_| UleError::parse::<Self>())
}
#[inline]
unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self {
core::str::from_utf8_unchecked(bytes)
}
}
unsafe impl<T> VarULE for [T]
where
T: ULE,
{
#[inline]
fn validate_bytes(slice: &[u8]) -> Result<(), UleError> {
T::validate_bytes(slice)
}
#[inline]
unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self {
T::slice_from_bytes_unchecked(bytes)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::ZeroSlice;
#[test]
fn test_array_ule_validate() {
let bytes: &[u8] = &[1, 2, 3, 4, 5, 6];
assert!(<[u8; 2] as ULE>::validate_bytes(bytes).is_ok());
assert!(<[u8; 3] as ULE>::validate_bytes(bytes).is_ok());
assert!(<[u8; 6] as ULE>::validate_bytes(bytes).is_ok());
assert!(<[u8; 4] as ULE>::validate_bytes(bytes).is_err());
assert!(<[u8; 5] as ULE>::validate_bytes(bytes).is_err());
assert!(<[u8; 7] as ULE>::validate_bytes(bytes).is_err());
let chars_6b: &[u8] = &[0x61, 0x00, 0x00, 0x62, 0x00, 0x00]; assert!(<[CharULE; 2] as ULE>::validate_bytes(chars_6b).is_ok());
let chars_9b: &[u8] = &[0x61, 0x00, 0x00, 0x62, 0x00, 0x00, 0x63, 0x00, 0x00]; assert!(<[CharULE; 2] as ULE>::validate_bytes(chars_9b).is_err());
assert!(ZeroSlice::<[u8; 3]>::parse_bytes(bytes).is_ok());
assert!(ZeroSlice::<[u8; 4]>::parse_bytes(bytes).is_err());
assert!(<[u8; 0] as ULE>::validate_bytes(&[]).is_err());
assert!(<[u8; 0] as ULE>::validate_bytes(bytes).is_err());
assert!(ZeroSlice::<[u8; 0]>::parse_bytes(&[]).is_err());
assert!(ZeroSlice::<[u8; 0]>::parse_bytes(bytes).is_err());
}
}