#![allow(dead_code, warnings)]
use std::path::PathBuf;
use clap::Parser;
#[derive(Debug, Default)]
struct PositionalArgs<'A> {
start: Option<&'A str>,
increment: Option<&'A str>,
end: &'A str
}
use std::ffi::OsStr;
use std::fmt::Debug;
macro_rules! parse_u64 {
($var:ident) => {
Some(
$var
.as_ref()
.parse::<u64>()
.expect( &format!("Could not parse '{:?}'", stringify!($var)) )
)
};
}
use std::convert::TryFrom;
impl<'A, T> TryFrom<&'A [T]> for PositionalArgs<'A>
where T: 'A + std::fmt::Display + Debug + AsRef<str>
{
type Error = &'static str;
fn try_from(mut vec: &'A [T]) -> Result<Self, Self::Error> {
if vec.len() > 3 {
panic!("Too many positional arguments")
}
let o = match (vec.get(0), vec.get(1), vec.get(2)) {
( Some(end), None, None ) => {
Self { end: end.as_ref(), .. Default::default() }
},
( Some(start), Some(end), None ) => {
Self {
end: end.as_ref(),
start: Some(start.as_ref()),
..Default::default()
}
},
( Some(start), Some(increment), Some(end) ) => {
Self {
end: end.as_ref(),
start: Some(start.as_ref()),
increment: Some(increment.as_ref()),
..Default::default()
}
},
_ => panic!("More than one positional argument is required")
};
Ok(o)
}
}
impl TryFrom<&mut Args> for letter_sequence::SequenceBuilder {
type Error = letter_sequence::SequenceError;
fn try_from(args: &mut Args) -> Result<Self, Self::Error> {
let positional_args: Vec<String> = std::mem::take(&mut args.args);
let positional_args: Vec<&str> = positional_args.iter().map(AsRef::as_ref).collect();
let positional_args: &[&str] = positional_args.as_slice();
let positional_args = PositionalArgs::try_from(positional_args).unwrap();
use letter_sequence::SequenceBuilder;
let step = positional_args
.increment
.map_or( Ok(1), |x| x.parse::<u32>() )?;
let builder = match (positional_args.start, positional_args.end) {
(Some(start), end) => SequenceBuilder::try_from( (start,end) ),
(None, end) => SequenceBuilder::try_from( ("1", end) ),
}.unwrap().inclusive().step(step);
Ok(builder)
}
}
#[derive(Parser, Debug)]
#[clap(author, version, about)]
struct Args {
#[clap(short, long)]
format: Option<String>,
#[clap(short, long)]
seperator: Option<String>,
#[clap(short = 'w', long)]
equal_width: Option<bool>,
#[clap(required=true)]
args: Vec<String>,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut opts = Args::from_args();
let mut seq = letter_sequence::SequenceBuilder::try_from(&mut opts)?
.build()?;
let sep = opts
.seperator
.unwrap_or("\n".to_string());
let mut first = true;
for e in seq {
if ( first ) {
print!("{}", e);
first = false;
}
else {
print!("{}{}", sep, e);
}
}
print!("\n");
Ok(())
}