#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
mod codes;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
pub use codes::version;
#[derive(Copy, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct JEP106Code {
pub id: u8,
pub cc: u8,
}
impl JEP106Code {
pub const fn new(cc: u8, id: u8) -> Self {
Self { id, cc }
}
pub const fn get(&self) -> Option<&'static str> {
get(self.cc, self.id)
}
pub const fn get_raw(cc: u8, id: u8) -> Option<&'static str> {
get(cc, id)
}
}
impl core::fmt::Debug for JEP106Code {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(
f,
"JEP106Code({{ cc: 0x{:02x?}, id: 0x{:02x?} }} => {:?})",
self.cc,
self.id,
self.get()
)
}
}
impl core::fmt::Display for JEP106Code {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
write!(f, "{}", self.get().unwrap_or("Unknown Manufacturer Code"))
}
}
const fn get(cc: u8, id: u8) -> Option<&'static str> {
if cc as usize >= codes::CODES.len() {
return None;
}
let cc_values = codes::CODES[cc as usize];
if id as usize >= cc_values.len() {
return None;
}
cc_values[id as usize]
}
#[test]
fn test_out_of_bound_access() {
let last_valid_cc = codes::CODES.len() - 1;
let last_valid_id = codes::CODES[last_valid_cc].len() - 1;
let _ = crate::get(last_valid_cc as u8, last_valid_id as u8);
assert!(crate::get(last_valid_cc as u8, (last_valid_id + 1) as u8).is_none());
assert!(crate::get((last_valid_cc + 1) as u8, last_valid_id as u8).is_none());
}