#![cfg_attr(all(not(test), not(feature = "std")), no_std)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![warn(missing_docs)]
#[cfg(feature = "alloc")]
extern crate alloc;
#[doc(hidden)]
pub mod _export {
pub mod _core {
pub use core::*;
}
}
pub mod buf_encoder;
pub mod display;
pub mod error;
mod iter;
pub mod parse;
#[cfg(feature = "serde")]
pub mod serde;
pub mod prelude {
#[doc(inline)]
pub use crate::{display::DisplayHex, parse::FromHex};
}
pub(crate) use table::Table;
#[rustfmt::skip] #[doc(inline)]
pub use self::{
display::DisplayHex,
error::{OddLengthStringError, HexToBytesError, HexToArrayError, InvalidCharError},
iter::{BytesToHexIter, HexToBytesIter, HexSliceToBytesIter},
parse::FromHex,
};
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum Case {
Lower,
Upper,
}
impl Default for Case {
#[inline]
fn default() -> Self { Case::Lower }
}
impl Case {
#[inline]
#[rustfmt::skip]
pub(crate) fn table(self) -> &'static Table {
match self {
Case::Lower => &Table::LOWER,
Case::Upper => &Table::UPPER,
}
}
}
mod table {
use arrayvec::ArrayString;
pub(crate) struct Table([u8; 16]);
impl Table {
pub(crate) const LOWER: Self = Table([
b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b', b'c', b'd',
b'e', b'f',
]);
pub(crate) const UPPER: Self = Table([
b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'A', b'B', b'C', b'D',
b'E', b'F',
]);
#[inline]
pub(crate) fn byte_to_hex(&self, byte: u8) -> ArrayString<2> {
let left = self.0[usize::from(byte.wrapping_shr(4))];
let right = self.0[usize::from(byte & 0x0F)];
ArrayString::from_byte_string(&[left, right]).expect("Table only contains valid ASCII")
}
}
}
#[macro_export]
macro_rules! test_hex_unwrap (($hex:expr) => (<Vec<u8> as $crate::FromHex>::from_hex($hex).unwrap()));
#[cfg(test)]
mod tests {
use crate::test_hex_unwrap as hex;
#[test]
fn parse_hex_into_vector() {
let got = hex!("deadbeef");
let want = vec![0xde, 0xad, 0xbe, 0xef];
assert_eq!(got, want)
}
}