use crate::result::{Error, Result};
use crate::util::check_ascii;
pub const PRODUCT_NAME_LEN: usize = 5;
#[repr(C)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct ProductName {
name: [u8; PRODUCT_NAME_LEN],
}
impl ProductName {
pub const fn new() -> Self {
Self {
name: [0; PRODUCT_NAME_LEN],
}
}
pub const fn name(&self) -> &[u8] {
&self.name
}
pub const fn bytes(self) -> [u8; PRODUCT_NAME_LEN] {
self.name
}
pub const fn try_from_bytes(val: &[u8]) -> Result<Self> {
match check_ascii(val, PRODUCT_NAME_LEN) {
Ok(_) => Ok(Self {
name: [val[0], val[1], val[2], val[3], val[4]],
}),
Err(err) => Err(err),
}
}
}
impl Default for ProductName {
fn default() -> Self {
Self::new()
}
}
impl From<ProductName> for [u8; PRODUCT_NAME_LEN] {
fn from(val: ProductName) -> Self {
val.bytes()
}
}
impl TryFrom<&[u8]> for ProductName {
type Error = Error;
fn try_from(val: &[u8]) -> Result<Self> {
Self::try_from_bytes(val)
}
}
impl<const N: usize> TryFrom<[u8; N]> for ProductName {
type Error = Error;
fn try_from(val: [u8; N]) -> Result<Self> {
Self::try_from_bytes(val.as_ref())
}
}
impl<const N: usize> TryFrom<&[u8; N]> for ProductName {
type Error = Error;
fn try_from(val: &[u8; N]) -> Result<Self> {
Self::try_from_bytes(val.as_ref())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_valid() {
(0..=u8::MAX)
.filter(|&c| (c as char).is_ascii())
.for_each(|c| {
let name = [c; PRODUCT_NAME_LEN];
let exp_name = ProductName { name };
assert_eq!(ProductName::try_from_bytes(name.as_ref()), Ok(exp_name));
assert_eq!(ProductName::try_from(name.as_ref()), Ok(exp_name));
assert_eq!(ProductName::try_from(name), Ok(exp_name));
assert_eq!(exp_name.bytes(), name);
assert_eq!(exp_name.name(), name.as_ref());
});
}
#[test]
fn test_invalid() {
(0..=u8::MAX)
.filter(|&c| !(c as char).is_ascii())
.for_each(|c| {
let name = [c; PRODUCT_NAME_LEN];
assert_eq!(
ProductName::try_from_bytes(name.as_ref()),
Err(Error::InvalidVariant(c as usize))
);
assert_eq!(
ProductName::try_from(name.as_ref()),
Err(Error::InvalidVariant(c as usize))
);
assert_eq!(
ProductName::try_from(name),
Err(Error::InvalidVariant(c as usize))
);
});
}
}