Started mod `args` for parsing arguments. Fortune for enumerate-ordered's current commit: Future small blessing − 末小吉master
parent
ba2680db8e
commit
e156e2cc1e
@ -0,0 +1,84 @@
|
|||||||
|
//! Arg parsing
|
||||||
|
use super::*;
|
||||||
|
use std::{
|
||||||
|
ffi::OsStr,
|
||||||
|
path::{
|
||||||
|
Path, PathBuf,
|
||||||
|
},
|
||||||
|
borrow::Cow,
|
||||||
|
};
|
||||||
|
use tokio::{
|
||||||
|
sync::{
|
||||||
|
mpsc,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
use futures::{
|
||||||
|
stream::{self, Stream, BoxStream, StreamExt,},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Parsed command-line args
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Args
|
||||||
|
{
|
||||||
|
paths: Option<Vec<PathBuf>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Args
|
||||||
|
{
|
||||||
|
/// Paths as an async stream
|
||||||
|
///
|
||||||
|
/// # Non-immediate
|
||||||
|
/// When input paths come from `stdin`, the output stream will be non-immediate.
|
||||||
|
pub fn paths(&self) -> BoxStream<'_, Cow<'_, Path>>
|
||||||
|
{
|
||||||
|
if let Some(paths) = self.paths.as_ref() {
|
||||||
|
stream::iter(paths.iter().map(|x| Cow::Borrowed(Path::new(x)))).boxed()
|
||||||
|
} else {
|
||||||
|
let (tx, rx) = mpsc::channel(128);
|
||||||
|
tokio::spawn(async move {
|
||||||
|
use tokio::io::{
|
||||||
|
self,
|
||||||
|
AsyncReadExt, AsyncBufReadExt
|
||||||
|
};
|
||||||
|
let mut stdin = {
|
||||||
|
tokio::io::BufReader::new(io::stdin())
|
||||||
|
};
|
||||||
|
let mut buf = Vec::with_capacity(1024);
|
||||||
|
loop
|
||||||
|
{
|
||||||
|
buf.clear();
|
||||||
|
use std::os::unix::prelude::*;
|
||||||
|
let n = match stdin.read_until(b'\n', &mut buf).await {
|
||||||
|
Ok(n) => n,
|
||||||
|
Err(e) => {
|
||||||
|
error!("paths: Failed to read input line: {}", e);
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if n == 0 {
|
||||||
|
trace!("paths: Stdin exhausted. Stopping read.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let path_bytes = &buf[..n];
|
||||||
|
let path = Path::new(OsStr::from_bytes(path_bytes));
|
||||||
|
if path.exists() {
|
||||||
|
if tx.send(path.to_owned()).await.is_err() {
|
||||||
|
trace!("paths: Stream dropped, cancelling stdin read.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tokio_stream::wrappers::ReceiverStream::new(rx).map(|x| Cow::Owned(x)).boxed()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn parse_args() -> eyre::Result<Args>
|
||||||
|
{
|
||||||
|
todo!("parse(std::env::args().skip(1))")
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: fn parse(args: impl IntoIterator<Item=String>) -> eyre::Result<Args>
|
||||||
|
|
Loading…
Reference in new issue