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