Initial commit
This commit is contained in:
commit
b61bf1f827
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
Cargo.lock
|
|
@ -0,0 +1,9 @@
|
|||
[package]
|
||||
name = "switches"
|
||||
version = "1.0.0"
|
||||
authors = ["Ben Bridle <bridle.benjamin@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
|
@ -0,0 +1,2 @@
|
|||
mod switches;
|
||||
pub use switches::Switches;
|
|
@ -0,0 +1,113 @@
|
|||
pub struct Switches {
|
||||
args: Vec<String>,
|
||||
}
|
||||
impl Switches {
|
||||
pub fn new(args: Vec<String>) -> Self {
|
||||
Self { args }
|
||||
}
|
||||
|
||||
pub fn from_env() -> Self {
|
||||
Self::new(std::env::args().collect())
|
||||
}
|
||||
|
||||
pub fn get(&mut self, switch: &str) -> SwitchBuilder {
|
||||
let builder = SwitchBuilder::new(&mut self.args);
|
||||
builder.or(switch)
|
||||
}
|
||||
|
||||
pub fn check_for_unused_arguments(&mut self) -> Result<(), Error> {
|
||||
if self.args.len() > 0 {
|
||||
Err(Error::UnexpectedArguments(self.args.clone()))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_value(&mut self) -> Option<String> {
|
||||
if self.args.is_empty() {
|
||||
return None;
|
||||
};
|
||||
Some(self.args.remove(0))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SwitchBuilder<'a> {
|
||||
args: &'a mut Vec<String>,
|
||||
matched_indices: Vec<usize>,
|
||||
matched_switches: Vec<String>,
|
||||
all_switches: Vec<String>,
|
||||
}
|
||||
|
||||
impl<'a> SwitchBuilder<'a> {
|
||||
pub fn new(args: &'a mut Vec<String>) -> Self {
|
||||
Self {
|
||||
args,
|
||||
matched_indices: Vec::new(),
|
||||
matched_switches: Vec::new(),
|
||||
all_switches: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn or(mut self, switch: &str) -> Self {
|
||||
self.all_switches.push(switch.to_string());
|
||||
for (index, arg) in self.args.iter().enumerate() {
|
||||
if arg == switch {
|
||||
self.matched_indices.push(index);
|
||||
self.matched_switches.push(arg.to_string());
|
||||
}
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
pub fn as_flag(mut self) -> Result<bool, Error> {
|
||||
let result = match self.matched_indices.len() {
|
||||
0 => Ok(false),
|
||||
1 => Ok(true),
|
||||
_ => Err(Error::MultipleMatchesFound(self.matched_switches.clone())),
|
||||
};
|
||||
self.remove_matches();
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn as_opt_string(&mut self) -> Result<Option<String>, Error> {
|
||||
let switch_index = match self.matched_indices.len() {
|
||||
0 => return Ok(None),
|
||||
1 => self.matched_indices[0],
|
||||
_ => return Err(Error::MultipleMatchesFound(self.matched_switches.clone())),
|
||||
};
|
||||
let switch = self.matched_switches[0].clone();
|
||||
let value_index = switch_index + 1;
|
||||
let value = match self.args.get(value_index) {
|
||||
Some(value) => {
|
||||
self.matched_indices.push(value_index);
|
||||
value.to_string()
|
||||
}
|
||||
None => return Err(Error::NoValueForSwitch(switch)),
|
||||
};
|
||||
if value.starts_with("-") {
|
||||
return Err(Error::NoValueForSwitch(switch));
|
||||
};
|
||||
self.remove_matches();
|
||||
return Ok(Some(value));
|
||||
}
|
||||
|
||||
pub fn as_string(&mut self) -> Result<String, Error> {
|
||||
match self.as_opt_string()? {
|
||||
Some(value) => Ok(value),
|
||||
None => Err(Error::NoMatchFound(self.all_switches.clone())),
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_matches(&mut self) {
|
||||
for index in self.matched_indices.iter().rev() {
|
||||
self.args.remove(*index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Error {
|
||||
MultipleMatchesFound(Vec<String>), // All of the switches that were matched
|
||||
NoMatchFound(Vec<String>), // All of the switches that were looked for
|
||||
NoValueForSwitch(String), //
|
||||
UnexpectedArguments(Vec<String>),
|
||||
}
|
Loading…
Reference in New Issue