use std::slice;
use crate::errors;
#[derive(Clone, Debug, Hash, PartialEq)]
pub enum Arg {
Chars(String, usize),
Bytes(Vec<u8>, usize),
}
impl Arg {
pub fn from_str(arg: &str, arg_id: usize) -> Self {
Self::Chars( arg.to_owned(), arg_id )
}
#[doc(hidden)]
pub fn from_bytes(arg: &[u8], arg_id: usize) -> Self {
Self::Bytes( arg.to_owned(), arg_id )
}
pub fn str_or_panic(&self) -> &str {
match self {
Arg::Chars(s, _) => s,
Arg::Bytes(_, idx) => panic!("argument #{} cannot be converted into a string", idx),
}
}
}
impl Eq for Arg {}
impl TryFrom<&Arg> for i64 {
type Error = errors::LibError;
fn try_from(value: &Arg) -> Result<Self, Self::Error> {
match value {
Arg::Chars(s, idx) => {
match s.parse::<i64>() {
Ok(int) => Ok(int),
Err(_) => Err(errors::LibError::ArgValueError(*idx, format!("cannot be converted into an integer: '{}'", s))),
}
},
Arg::Bytes(_, idx) => Err(errors::LibError::ArgTypeError(*idx, "this argument cannot be converted into an integer".to_owned())),
}
}
}
impl<'s> TryFrom<&'s Arg> for &'s str {
type Error = errors::LibError;
fn try_from(value: &'s Arg) -> Result<Self, Self::Error> {
match value {
Arg::Chars(s, _idx) => Ok(s),
Arg::Bytes(_, idx) => Err(errors::LibError::ArgTypeError(*idx, "this argument cannot be converted into a string".to_owned())),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Args {
args: Vec<Arg>,
}
impl Args {
pub fn from(arguments: &[Arg]) -> Args {
Args { args: arguments.to_vec() }
}
pub fn add(&mut self, arg: Arg) {
self.args.push(arg);
}
pub fn len(&self) -> usize {
self.args.len()
}
pub fn get(&self, index: usize) -> Result<&Arg, errors::LibError> {
match self.args.get(index) {
Some(arg) => Ok(arg),
None => Err(errors::LibError::IOError(format!("argument {} does not exist", index))),
}
}
pub fn get_or_default<'s, 'd: 's>(&'s self, index: usize, default: &'d Arg) -> &Arg {
match self.args.get(index) {
Some(arg) => arg,
None => default,
}
}
pub fn iter<'s>(&'s self) -> slice::Iter<'s, Arg> {
self.args.iter()
}
}