use std::fs::File;
use std::io::{BufRead, BufReader};
use std::string::ToString;
pub fn convert(text: &String) -> Result<Vec<u8>, String> {
let mut target = format_text(&text).chars().collect::<Vec<char>>();
let mut byte_vec = vec![];
while target.len() > 0 {
let byte = str_2_binary(target[..2].to_vec())?;
byte_vec.push(byte);
target = target[2..].to_vec();
}
Ok(byte_vec.clone())
}
pub fn convert_line(line: &Vec<String>) -> Result<Vec<u8>, String> {
let join_string = line.join("");
convert(&join_string)
}
pub fn convert_file(file: &File) -> Result<Vec<u8>, String> {
let mut string = "".to_string();
let mut reader = BufReader::new(file);
loop {
let mut line = "".to_string();
let len = match reader.read_line(&mut line) {
Ok(len) => len,
Err(err) => return Err(format!("{}", err)),
};
if len == 0 {
break;
}
string.push_str(line.as_str());
}
convert(&string)
}
fn format_text(text: &String) -> String {
let mut format_text = "".to_string();
for c in text.chars() {
match c {
' ' | '\n' | '\r' => continue,
_ => format_text.push(c),
}
}
if format_text.len() % 2 != 0 {
format_text.push('0');
}
format_text
}
fn str_2_binary(target: Vec<char>) -> Result<u8, String> {
if target.len() != 2 {
return Err(format!("Target is not two characters. target={:?}", target));
}
let upper = char_2_hex(target[0])?;
let lower = char_2_hex(target[1])?;
Ok((upper << 4) + lower)
}
fn char_2_hex(target: char) -> Result<u8, String> {
match target {
'0' => Ok(0),
'1' => Ok(1),
'2' => Ok(2),
'3' => Ok(3),
'4' => Ok(4),
'5' => Ok(5),
'6' => Ok(6),
'7' => Ok(7),
'8' => Ok(8),
'9' => Ok(9),
'A' | 'a' => Ok(10),
'B' | 'b' => Ok(11),
'C' | 'c' => Ok(12),
'D' | 'd' => Ok(13),
'E' | 'e' => Ok(14),
'F' | 'f' => Ok(15),
_ => return Err(format!("It is not a hexadecimal representation. target={}", target)),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_format_text_normal() {
let expect = "1234567890";
assert_eq!(expect, format_text(&"123456789".to_string()))
}
#[test]
fn test_format_text_wide() {
let expect = "1234";
assert_eq!(expect, format_text(&"1234".to_string()))
}
#[test]
fn test_format_text_append_zero() {
let expect = "1234xyz0";
assert_eq!(expect, format_text(&"1234xyz".to_string()))
}
#[test]
fn test_format_text_remove_space() {
let expect = "001122334455";
assert_eq!(expect, format_text(&" 00 11 22 33 44 55 ".to_string()))
}
#[test]
fn test_format_text_remove_n() {
let expect = "abcd0123";
assert_eq!(expect, format_text(&" abcd\n0123".to_string()))
}
#[test]
fn test_format_text_remove_r() {
let expect = "xyz56789";
assert_eq!(expect, format_text(&" xyz\r56789".to_string()))
}
#[test]
fn test_format_text_remove_composite() {
let expect = "xyz56789";
assert_eq!(expect, format_text(&" xyz 56\r78\n9".to_string()))
}
#[test]
fn test_str_2_binary_08() {
match str_2_binary(vec!['0', '8']) {
Ok(ok) => assert_eq!(0x08, ok),
Err(err) => panic!("{}", err),
}
}
#[test]
fn test_str_2_binary_0a() {
match str_2_binary(vec!['0', 'a']) {
Ok(ok) => assert_eq!(0x0a, ok),
Err(err) => panic!("{}", err),
}
match str_2_binary(vec!['0', 'A']) {
Ok(ok) => assert_eq!(0x0a, ok),
Err(err) => panic!("{}", err),
}
}
#[test]
fn test_str_2_binary_f1() {
match str_2_binary(vec!['f', '1']) {
Ok(ok) => assert_eq!(0xf1, ok),
Err(err) => panic!("{}", err),
}
match str_2_binary(vec!['F', '1']) {
Ok(ok) => assert_eq!(0xf1, ok),
Err(err) => panic!("{}", err),
}
}
#[test]
fn test_str_2_binary_err_000() {
let err_msg = "Target is not two characters. target=['0', '0', '0']";
match str_2_binary(vec!['0', '0', '0']) {
Ok(ok) => panic!("エラーが発生しませんでした。Ok={}", ok),
Err(err) => assert_eq!(err_msg, err),
}
}
#[test]
fn test_str_2_binary_err_1() {
let err_msg = "Target is not two characters. target=['1']";
match str_2_binary(vec!['1']) {
Ok(ok) => panic!("エラーが発生しませんでした。Ok={}", ok),
Err(err) => assert_eq!(err_msg, err),
}
}
#[test]
fn test_str_2_binary_err_0z() {
let err_msg = "It is not a hexadecimal representation. target=z";
match str_2_binary(vec!['0', 'z']) {
Ok(ok) => panic!("エラーが発生しませんでした。Ok={}", ok),
Err(err) => assert_eq!(err_msg, err),
}
}
#[test]
fn test_str_2_binary_err_wide() {
let err_msg = "It is not a hexadecimal representation. target=1";
match str_2_binary(vec!['1', '0']) {
Ok(ok) => panic!("エラーが発生しませんでした。Ok={}", ok),
Err(err) => assert_eq!(err_msg, err),
}
}
}