use crate::input::ByteCounter;
use lazy_static::lazy_static;
use std::path::PathBuf;
use std::str::FromStr;
use structopt::StructOpt;
pub const ASCII_ENC_LABEL: &str = "ascii";
pub const ENCODING_DEFAULT: &str = "UTF-8";
pub const CHARS_MIN_DEFAULT: u8 = 4;
pub const COUNTER_OFFSET_DEFAULT: ByteCounter = 0;
pub const OUTPUT_LINE_CHAR_NB_MAX_DEFAULT: usize = 64;
pub const OUTPUT_LINE_CHAR_NB_MIN: usize = 6;
#[derive(Debug, PartialEq, StructOpt)]
#[structopt(
name = "stringsext",
about = "Find multi-byte encoded strings in binary data."
)]
pub struct Args {
#[structopt(long, short = "a")]
pub ascii_filter: Option<String>,
#[structopt(long, short = "c")]
pub no_metadata: bool,
#[structopt(long, short = "d")]
pub debug_option: bool,
#[structopt(name = "FILE", parse(from_os_str))]
pub inputs: Vec<PathBuf>,
#[structopt(long, short = "e")]
pub encoding: Vec<String>,
#[structopt(long, short = "g")]
pub grep_char: Option<String>,
#[structopt(long, short = "l")]
pub list_encodings: bool,
#[structopt(long, short = "n")]
pub chars_min: Option<String>,
#[structopt(long, short = "r")]
pub same_unicode_block: bool,
#[structopt(long, short = "p", parse(from_os_str))]
pub output: Option<PathBuf>,
#[structopt(long, short = "q")]
pub output_line_len: Option<String>,
#[structopt(long, short = "s")]
pub counter_offset: Option<String>,
#[structopt(long, short = "t")]
pub radix: Option<Radix>,
#[structopt(long, short = "u")]
pub unicode_block_filter: Option<String>,
#[structopt(long, short = "V")]
pub version: bool,
}
#[derive(Debug, Hash, Clone, Eq, PartialEq, Copy)]
pub enum Radix {
O,
X,
D,
}
impl FromStr for Radix {
type Err = String;
fn from_str(rad: &str) -> Result<Radix, Self::Err> {
match &*rad.to_ascii_lowercase() {
"o" => Ok(Radix::O),
"x" => Ok(Radix::X),
"d" => Ok(Radix::D),
_ => Err(String::from("can not convert radix variant")),
}
}
}
lazy_static! {
pub static ref ARGS : Args = Args::from_args();
}
#[cfg(test)]
mod tests {
#[test]
fn test_arg_parser() {
use super::{Args, Radix};
use std::path::PathBuf;
use structopt::StructOpt;
let argv = vec![
"stringsext",
"-d",
"-n",
"10",
"-g",
"64",
"-e",
"ascii",
"-e",
"utf-8",
"-V",
"-l",
"-s",
"1500",
"-p",
"outfile",
"-q",
"40",
"-t",
"o",
"-r",
"infile1",
"infile2",
];
let args = Args::from_iter(argv);
assert_eq!(args.inputs[0], PathBuf::from("infile1"));
assert_eq!(args.inputs[1], PathBuf::from("infile2"));
assert!(args.debug_option);
assert_eq!(
args.encoding,
vec!["ascii".to_string(), "utf-8".to_string()]
);
assert!(args.version);
assert!(args.list_encodings);
assert_eq!(args.chars_min, Some("10".to_string()));
assert!(args.same_unicode_block);
assert_eq!(args.grep_char, Some("64".to_string()));
assert_eq!(args.radix, Some(Radix::O));
assert_eq!(args.counter_offset, Some("1500".to_string()));
assert_eq!(args.output, Some(PathBuf::from("outfile")));
assert_eq!(args.output_line_len, Some("40".to_string()));
assert!(!args.no_metadata);
}
}