parent
f44a998fe8
commit
0101bb5c5f
@ -0,0 +1,63 @@
|
||||
use crate::{
|
||||
opt::{Opt, Options},
|
||||
};
|
||||
|
||||
pub enum OperationMode {
|
||||
Normal(Options, Vec<String>),
|
||||
Help,
|
||||
}
|
||||
|
||||
pub fn parse() -> Result<OperationMode, &'static str>
|
||||
{
|
||||
let mut opt = Options::new();
|
||||
let mut files = Vec::new();
|
||||
let mut look = true;
|
||||
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
let mut i=1;
|
||||
while i < args.len()
|
||||
{
|
||||
let arg = &args[i];
|
||||
match arg.as_str() {
|
||||
"-h" if i == 1 => {
|
||||
return Ok(OperationMode::Help);
|
||||
},
|
||||
"-s" if look => {
|
||||
opt |= Opt::Silent;
|
||||
},
|
||||
"-e" if look => {
|
||||
if i < args.len() - 1 {
|
||||
opt |= Opt::Execute(args[i+1].to_owned());
|
||||
} else {
|
||||
return Err("-e expects an argument that wasn't given.");
|
||||
}
|
||||
i += 1;
|
||||
},
|
||||
"-o" if look => {
|
||||
if i < args.len() - 1 {
|
||||
opt |= Opt::Output(args[i+1].to_owned());
|
||||
} else {
|
||||
return Err("-o expects an argument that wasn't given.");
|
||||
}
|
||||
i += 1;
|
||||
},
|
||||
"-" if look => look=false,
|
||||
other => {
|
||||
files.push(other.to_owned());
|
||||
look=false;
|
||||
},
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if files.len() < 1 {
|
||||
return Err("No files specified. For help run with `-h`");
|
||||
}
|
||||
|
||||
Ok(OperationMode::Normal(opt, files))
|
||||
}
|
||||
|
||||
pub fn program_name() -> String
|
||||
{
|
||||
std::env::args().next().unwrap()
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
iter::FromIterator,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Opt
|
||||
{
|
||||
Silent,
|
||||
Execute(String),
|
||||
Output(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct Options(HashSet<Opt>);
|
||||
|
||||
impl Options
|
||||
{
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self(HashSet::new())
|
||||
}
|
||||
|
||||
pub fn has_tag(&self, opt: &Opt) -> bool {
|
||||
for x in self.0.iter() {
|
||||
if x == opt {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
//operators
|
||||
|
||||
use std::ops;
|
||||
// opts |= opt
|
||||
impl ops::BitOrAssign<Opt> for Options
|
||||
{
|
||||
fn bitor_assign(&mut self, rhs: Opt)
|
||||
{
|
||||
self.0.insert(rhs);
|
||||
}
|
||||
}
|
||||
// opts |= other_opts
|
||||
impl ops::BitOrAssign for Options
|
||||
{
|
||||
fn bitor_assign(&mut self, other: Self)
|
||||
{
|
||||
self.0.extend(other.0)
|
||||
}
|
||||
}
|
||||
|
||||
// opt1 | opt2
|
||||
impl ops::BitOr for Opt
|
||||
{
|
||||
type Output = Options;
|
||||
|
||||
fn bitor(self, other: Self) -> <Self as ops::BitOr>::Output
|
||||
{
|
||||
Options::from([self, other].to_vec())
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::BitAnd<Opt> for Options
|
||||
{
|
||||
type Output = bool;
|
||||
|
||||
fn bitand(self, other: Opt) -> bool
|
||||
{
|
||||
self.has_tag(&other)
|
||||
}
|
||||
}
|
||||
impl ops::BitAnd for Options
|
||||
{
|
||||
type Output = bool;
|
||||
fn bitand(self, other: Self) -> bool
|
||||
{
|
||||
for x in other.0.iter()
|
||||
{
|
||||
if !self.has_tag(x) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<Opt>> for Options
|
||||
{
|
||||
fn from(other: Vec<Opt>) -> Self{
|
||||
let mut hs = HashSet::new();
|
||||
for x in other.into_iter()
|
||||
{
|
||||
hs.insert(x);
|
||||
}
|
||||
Self(hs)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Options> for Vec<Opt>
|
||||
{
|
||||
fn from(other: Options) -> Vec<Opt>
|
||||
{
|
||||
Vec::from_iter(other.0.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for Options
|
||||
{
|
||||
type Item = Opt;
|
||||
type IntoIter = std::vec::IntoIter<Opt>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter
|
||||
{
|
||||
Vec::from(self).into_iter()
|
||||
}
|
||||
}
|
Loading…
Reference in new issue