summaryrefslogtreecommitdiffstats
path: root/src/config.rs
diff options
context:
space:
mode:
authorToby Vincent <tobyv@tobyvin.dev>2024-02-24 18:09:58 -0600
committerToby Vincent <tobyv@tobyvin.dev>2024-02-24 18:09:58 -0600
commit04814c4996140871674d7ce5552f55d9ba07615a (patch)
tree804e57beed1a4d3c2b8908523c0453f4655b5bbd /src/config.rs
parent12cc1358ad636c194a2464561939ff72fb8aaa9c (diff)
feat!: remove tmux functionalilty and more async
Diffstat (limited to 'src/config.rs')
-rw-r--r--src/config.rs104
1 files changed, 53 insertions, 51 deletions
diff --git a/src/config.rs b/src/config.rs
index c5f6db5..44d500e 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,4 +1,4 @@
-use std::{path::PathBuf, str::FromStr, sync::atomic::AtomicBool};
+use std::{collections::HashSet, path::PathBuf, str::FromStr, sync::atomic::AtomicBool};
use clap::Parser;
#[derive(Debug, Clone, Parser)]
@@ -11,72 +11,74 @@ pub struct Config {
#[arg(short, long)]
pub resolve: bool,
- /// include host in output
- #[arg(short, long)]
- pub include: Vec<sshr::Host>,
+ /// include <NAME>. If <NAME> is a valid path or '-', hosts with be read from the file or
+ /// stdin, respectivly.
+ #[arg(short, long, id = "NAME")]
+ pub include: Vec<IncludeExclude>,
- /// include lines from file, use '-' for stdin
- #[arg(short = 'I', long)]
- pub include_file: Vec<FileOrStdin>,
+ /// include <NAME>. If <NAME> is a valid path or '-', hosts with be read from the file or
+ /// stdin, respectivly.
+ #[arg(short, long, id = "HOST")]
+ pub exclude: Vec<IncludeExclude>,
+}
- /// exclude host from output
- #[arg(short, long)]
- pub exclude: Vec<sshr::Host>,
+impl Config {
+ pub fn included(&self) -> std::io::Result<HashSet<String>> {
+ Self::collect_values(&self.include)
+ }
- /// include lines from file, use '-' for stdin
- #[arg(short = 'E', long)]
- pub exclude_file: Vec<FileOrStdin>,
+ pub fn excluded(&self) -> std::io::Result<HashSet<String>> {
+ Self::collect_values(&self.exclude)
+ }
+
+ fn collect_values(values: &[IncludeExclude]) -> std::io::Result<HashSet<String>> {
+ use std::io::BufRead;
+ values.iter().try_fold(HashSet::new(), |mut acc, item| {
+ match item {
+ IncludeExclude::Stdin => {
+ acc.extend(std::io::stdin().lock().lines().map_while(Result::ok))
+ }
+ IncludeExclude::File(filepath) => acc.extend(
+ std::io::BufReader::new(std::fs::File::open(filepath)?)
+ .lines()
+ .map_while(Result::ok),
+ ),
+ IncludeExclude::Item(s) => {
+ acc.insert(s.to_owned());
+ }
+ }
+ Ok(acc)
+ })
+ }
}
static READ_STDIN: AtomicBool = AtomicBool::new(false);
#[derive(Debug, Clone)]
-pub enum FileOrStdin {
+pub enum IncludeExclude {
Stdin,
+ Item(String),
File(PathBuf),
}
-impl FileOrStdin {
- pub fn hosts(self) -> Result<Vec<sshr::Host>, anyhow::Error> {
- use std::io::Read;
- let mut buf = String::new();
- let _ = self.into_reader()?.read_to_string(&mut buf)?;
- buf.lines()
- .map(|s| s.trim_end().parse())
- .collect::<Result<Vec<_>, _>>()
- .map_err(|e| anyhow::format_err!("{e}"))
- }
-
- pub fn into_reader(&self) -> Result<impl std::io::Read, anyhow::Error> {
- let input: Box<dyn std::io::Read + 'static> = match &self {
- Self::Stdin => Box::new(std::io::stdin()),
- Self::File(filepath) => {
- let f = std::fs::File::open(filepath)?;
- Box::new(f)
- }
- };
- Ok(input)
- }
-}
-
-impl FromStr for FileOrStdin {
+impl FromStr for IncludeExclude {
type Err = std::io::Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
- match s {
- "-" => {
- if READ_STDIN.load(std::sync::atomic::Ordering::Acquire) {
- return Err(std::io::Error::new(
- std::io::ErrorKind::Other,
- "stdin argument used more than once",
- ));
- }
- READ_STDIN.store(true, std::sync::atomic::Ordering::SeqCst);
- Ok(Self::Stdin)
+ if s == "-" {
+ if READ_STDIN.load(std::sync::atomic::Ordering::Acquire) {
+ return Err(std::io::Error::new(
+ std::io::ErrorKind::Other,
+ "stdin argument used more than once",
+ ));
+ }
+ READ_STDIN.store(true, std::sync::atomic::Ordering::SeqCst);
+ Ok(Self::Stdin)
+ } else {
+ match PathBuf::from_str(s) {
+ Ok(path) if path.exists() => Ok(Self::File(path)),
+ _ => Ok(Self::Item(s.to_owned())),
}
- path => PathBuf::from_str(path)
- .map(Self::File)
- .map_err(|_| unreachable!()),
}
}
}