Added default formatters + error handling

This commit is contained in:
2022-04-09 12:34:15 -06:00
parent f8ba81e2ca
commit 59351fb699
8 changed files with 337 additions and 21 deletions
+47
View File
@@ -0,0 +1,47 @@
use std::error::Error;
use std::fmt::{Display, Formatter};
use crate::parser::ByteArrayParseErr;
use crate::formatter::format::FormatError;
use crate::formatter::FormatConfigError;
#[derive(Debug)]
pub enum FormatyError {
ByteArrayParseError(ByteArrayParseErr),
FormatError(FormatError),
FormatConfigError(FormatConfigError),
FormatNotFound(String)
}
impl From<ByteArrayParseErr> for FormatyError {
fn from(e: ByteArrayParseErr) -> Self {
Self::ByteArrayParseError(e)
}
}
impl From<FormatError> for FormatyError {
fn from(e: FormatError) -> Self {
Self::FormatError(e)
}
}
impl From<FormatConfigError> for FormatyError {
fn from(e: FormatConfigError) -> Self {
Self::FormatConfigError(e)
}
}
impl Display for FormatyError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let err_msg = match self {
FormatyError::ByteArrayParseError(e) => e.to_string(),
FormatyError::FormatError(e) => e.to_string(),
FormatyError::FormatConfigError(e) => e.to_string(),
FormatyError::FormatNotFound(err_msg) => format!("'{}' config not found.", err_msg)
};
write!(f, "{}", err_msg)
}
}
impl Error for FormatyError {}
+67 -6
View File
@@ -5,7 +5,56 @@ use crate::formatter::format::Format;
use serde::Deserialize;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::path::PathBuf;
use rust_embed::RustEmbed;
use std::str;
use std::str::Utf8Error;
use std::fmt::{Display, Formatter};
use std::error::Error;
#[derive(Debug)]
pub enum FormatConfigError {
IOError(std::io::Error),
TomlError(toml::de::Error),
Utf8Error(Utf8Error)
}
impl Error for FormatConfigError {}
impl From<std::io::Error> for FormatConfigError {
fn from(e: std::io::Error) -> Self {
Self::IOError(e)
}
}
impl From<toml::de::Error> for FormatConfigError {
fn from(e: toml::de::Error) -> Self {
Self::TomlError(e)
}
}
impl From<Utf8Error> for FormatConfigError {
fn from(e: Utf8Error) -> Self {
Self::Utf8Error(e)
}
}
impl Display for FormatConfigError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let err_msg = match self {
FormatConfigError::IOError(e) => e.to_string(),
FormatConfigError::TomlError(e) => e.to_string(),
FormatConfigError::Utf8Error(e) => e.to_string()
};
write!(f, "Format Config Error: {}", err_msg)
}
}
#[derive(RustEmbed)]
#[folder = "formats/"]
#[include = "*.toml"]
struct BuiltInFormats;
#[derive(Debug, Deserialize, Clone)]
pub struct FormatConfig {
@@ -13,13 +62,25 @@ pub struct FormatConfig {
}
impl FormatConfig {
pub fn new(config_path: &Path) -> Result<Self, std::io::Error> {
let mut config = File::open(config_path)?;
pub fn new(config_path: &Option<PathBuf>) -> Result<Self, FormatConfigError> {
let mut contents = String::new();
config.read_to_string(&mut contents)?;
if let Some(config_path) = config_path {
let mut config = File::open(config_path)?;
config.read_to_string(&mut contents)?;
}
Ok(toml::from_str(&contents).unwrap())
for format_file_path in BuiltInFormats::iter() {
if format_file_path.ends_with("md") {
continue;
}
let format_file = BuiltInFormats::get(&format_file_path).unwrap();
contents.push_str(str::from_utf8(&format_file.data).unwrap());
}
Ok(toml::from_str(&contents)?)
}
}
+20 -14
View File
@@ -2,16 +2,18 @@ use crate::parser::parse_bytes_from_input_arg;
use formatter::FormatConfig;
use std::path::PathBuf;
use structopt::StructOpt;
use crate::error::FormatyError;
mod byte_stream;
mod formatter;
mod parser;
mod error;
#[derive(Debug, StructOpt)]
#[structopt(name = "Formaty", about = "Arbitrary Binary Data Formatting")]
pub struct Args {
#[structopt(parse(from_os_str), help = "Path to the format config")]
config: PathBuf,
#[structopt(short = "c", long="config", parse(from_os_str), help = "Path to the format config")]
config: Option<PathBuf>,
#[structopt(help = "Format to parse data as")]
format: String,
@@ -20,23 +22,27 @@ pub struct Args {
data: Vec<String>,
}
fn main() {
fn formaty() -> Result<(), FormatyError> {
let args: Args = Args::from_args();
let config = FormatConfig::new(&args.config).unwrap();
let config = FormatConfig::new(&args.config)?;
let format = match config.formats.iter().find(|f| f.name == args.format) {
None => {
println!("Format not found in config file");
return;
}
Some(format) => format,
};
let format = config.formats.iter().find(|f| f.name == args.format).ok_or(FormatyError::FormatNotFound(args.format.to_string()))?;
let data = parse_bytes_from_input_arg(args.data).unwrap();
match format.format_data(&data) {
Ok(data_str) => println!("{}", data_str),
Err(_) => println!("Error formatting data"),
let data = format.format_data(&data)?;
println!("{}", data);
Ok(())
}
fn main() {
match formaty() {
Ok(_) => {}
Err(e) => {
println!("Error formatting data: {}", e.to_string())
}
}
}
+12
View File
@@ -1,4 +1,5 @@
use std::num::ParseIntError;
use std::fmt::{Display, Formatter};
#[derive(Debug, Clone)]
pub enum ByteArrayParseErr {
@@ -12,6 +13,17 @@ impl From<ParseIntError> for ByteArrayParseErr {
}
}
impl Display for ByteArrayParseErr {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let err_msg = match self {
ByteArrayParseErr::EmptySrcArray => "Provided array is empty!".to_string(),
ByteArrayParseErr::ParseIntError(e) => format!("Failed to parse as int: {}", e),
};
write!(f, "{}", err_msg)
}
}
fn bytes_from_str_array(src: Vec<String>) -> Result<Vec<u8>, ByteArrayParseErr> {
src.iter()
.map(|element| {