You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
enumerate-ordered/src/args.rs

95 lines
2.1 KiB

//! 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;
},
};
trace!("paths: buffer: {:?}", &buf[..]);
if n == 0 {
trace!("paths: Stdin exhausted. Exiting.");
break;
}
let path_bytes = &buf[..n];
let path_bytes = if path_bytes.len() == 1 {
trace!("paths: Ignoring empty line. Yielding then continuing.");
tokio::task::yield_now().await;
continue;
} else {
&path_bytes[.. (path_bytes.len()-1)]
};
let path = Path::new(OsStr::from_bytes(path_bytes));
trace!("Read path {:?}", path);
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>
{
//return Ok(Args { paths: None });
todo!("parse(std::env::args().skip(1))")
}
//TODO: fn parse(args: impl IntoIterator<Item=String>) -> eyre::Result<Args>