use crate::Vector;
use std::fmt;
use std::mem;
fn u8_to_bin(n: &u8) -> Bin {
format!("{:08b}", n)
}
fn bin_to_u8(b: &Bin) -> u8 {
u8::from_str_radix(b, 2).expect("Invalid binary string")
}
fn u8_to_hex(n: &u8) -> String {
format!("{:02x}", n)
}
fn hex_to_u8(h: &str) -> u8 {
u8::from_str_radix(h, 16).expect("Invalid hex string")
}
type Byte = u8;
#[derive(Debug)]
pub struct Bytes<const BIG_ENDIAN: bool = true>{
pub vec: Vector<Byte>
}
#[derive(Clone, Debug)]
pub struct Hex(pub String);
pub type Bin = String;
#[derive(Debug)]
pub struct Bins(pub Vector<Bin>);
impl Into<String> for &Bins {
fn into(self) -> String {
self.0.join(" ")
}
}
pub trait DebugBytes {
fn print(&self);
}
impl fmt::Display for Hex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:}", self.0)
}
}
impl DebugBytes for Bytes<true> {
fn print(&self) {
println!("\n----> Bytes: {:?}", self);
self.as_slice().print();
self.to_int128().unwrap().print();
self.to_bin().print();
self.to_hex().print();
println!();
}
}
impl DebugBytes for i128 {
fn print(&self) {
let p: *const i128 = &*self;
let view: Vector<Byte> = Vector {
ptr: p as *mut Byte,
cap: 16,
len: 16,
};
println!("-> i128: {:?}; {:?}", self, view);
std::mem::forget(view);
}
}
impl DebugBytes for &[Byte] {
fn print(&self) {
println!("-> &[u8]: {:?}", self);
}
}
impl DebugBytes for Hex {
fn print(&self) {
println!("-> Hex: {:?}", self.0);
}
}
impl DebugBytes for Bins {
fn print(&self) {
let s: String = self.into();
println!("-> Bins: [{:}]", s);
}
}
impl<const BE: bool> Bytes<BE> {
pub fn as_slice(&self) -> &[Byte] {
self.vec.as_slice()
}
pub fn to_int128(&self) -> Result<i128, String> {
let s1 = size_of::<i128>();
let s2 = self.vec.len_bytes();
if s2 > s1 {
return Err("Bytes length is too big".to_string());
}
unsafe {
let ptr: *const i128 = self.vec.as_ptr() as *const i128;
Ok(ptr.read())
}
}
pub fn to_bin(&self) -> Bins {
let v: Vector<Bin> = self.vec.iter().map(u8_to_bin).collect();
let a = Bins(v);
a
}
pub fn to_hex(&self) -> Hex {
let hex_string = self.vec.iter()
.map(u8_to_hex)
.collect::<String>();
Hex(hex_string)
}
pub fn from_bytes(from: &[Byte]) -> Self {
Self {
vec: Vector::from_slice_copy(from)
}
}
pub fn from_int(from: &i128) -> Self {
let ptr: *const i128 = from;
let ptr_u8: *mut u8 = ptr as *mut u8;
let size: usize = mem::size_of::<i128>() / mem::size_of::<Byte>();
let slice = unsafe {
std::slice::from_raw_parts(ptr_u8, size)
};
Self {
vec: Vector::from_slice_copy(slice)
}
}
pub fn from_bins(from: &Bins) -> Self {
let bytes: Vector<Byte> = from.0.iter().map(bin_to_u8).collect();
Self {
vec: bytes
}
}
pub fn from_hex(from: &Hex) -> Self {
let mut v: Vector<Byte> = Vector::new(0);
for i in (0..from.0.len()).step_by(2) {
let b: u8 = hex_to_u8(&from.0[i..i+2]);
v.push(b);
}
Self {
vec: v
}
}
}
impl From<Vector<u8>> for Bytes {
fn from(value: Vector<u8>) -> Self {
Self {
vec: value
}
}
}
impl Into<Vector<u8>> for Bytes {
fn into(self) -> Vector<u8> {
self.vec
}
}
impl From<Vec<u8>> for Bytes {
fn from(value: Vec<u8>) -> Self {
Self {
vec: Vector::from(value)
}
}
}
impl Into<Vec<u8>> for Bytes {
fn into(self) -> Vec<u8> {
self.vec.into()
}
}
impl Default for Bytes {
fn default() -> Self {
Self {
vec: Vector::new(0),
}
}
}