use std::string::FromUtf8Error;
pub struct StringBuilder(Vec<u8>);
impl StringBuilder {
fn append<T: AsRef<str>>(self: &mut Self, text: T) {
for b in text.as_ref().bytes() { self.0.push(b) }
}
fn append_char(self: &mut Self, c: char) {
self.append(String::from(c))
}
fn string(self: &mut Self) -> Result<String, FromUtf8Error> {
String::from_utf8(self.0.clone())
}
fn new() -> StringBuilder { StringBuilder(Vec::new()) }
fn len(self: &Self) -> usize { self.0.len() }
}
pub fn to_dump(data: &[u8]) -> String {
let mut offset = 0usize;
let mut counter = 0;
let mut result = StringBuilder::new();
fn ascii_dump(result: &mut StringBuilder, counter: usize, data: &[u8], offset: usize) {
for i in counter..16 { result.append(" "); }
result.append("|");
for i in 0..counter {
let b = data[offset - counter + i];
if b >= 32 && b <= 127 {
result.append_char(b as char)
} else {
result.append_char('.');
}
}
for i in counter..16 { result.append_char(' '); }
result.append("|\n");
}
while offset < data.len() {
if counter == 0 {
result.append(format!("{:04X} ", offset))
}
counter += 1;
result.append(format!("{:02x} ", data[offset]));
offset += 1;
if counter == 16 {
ascii_dump(&mut result, counter, data, offset);
counter = 0;
}
}
if counter != 0 { ascii_dump(&mut result, counter, data, offset); }
result.string().unwrap()
}
pub fn to_hex<T: AsRef<[u8]>>(source: T) -> Result<String,FromUtf8Error> {
let mut result = StringBuilder::new();
for b in source.as_ref() {
if result.len() != 0 { result.append( " ") }
result.append(format!("{:02x}", b))
}
result.string()
}
pub trait ToDump {
fn to_dump(&self) -> String;
}
impl ToDump for &[u8] {
fn to_dump(&self) -> String{
to_dump(self)
}
}
impl ToDump for Vec<u8> {
fn to_dump(&self) -> String {
to_dump(&self)
}
}