use arboard::Clipboard;
use miette::*;
use shadow_rs::shadow;
use std::io::{stdin, IsTerminal, Read};
use cli::*;
pub mod cli;
mod examples;
shadow!(build);
pub fn run(cli: Args) -> Result<()> {
if stdin().is_terminal() {
handle_terminal_input(cli)
} else {
handle_non_terminal_input(cli)
}
}
pub fn handle_terminal_input(cli: Args) -> Result<()> {
if let Some(text) = cli.text {
set_clipboard_text(&text)
} else {
print_clipboard_text()
}
}
pub fn handle_non_terminal_input(cli: Args) -> Result<()> {
if cli.text.is_some() {
return Err(miette!(
labels = vec![LabeledSpan::new(
Some("here".to_string()),
build::PROJECT_NAME.len() + 1,
cli.text.as_ref().unwrap().len()
)],
"Cannot read from stdin and provide text at the same time."
)
.with_source_code(format!(
"{} {}",
build::PROJECT_NAME,
cli.text.as_ref().unwrap()
)));
}
read_from_stdin_and_set_clipboard(stdin())
}
pub fn set_clipboard_text(text: &str) -> Result<()> {
let mut clipboard = Clipboard::new().into_diagnostic()?;
clipboard.set_text(text).into_diagnostic()?;
Ok(())
}
pub fn print_clipboard_text() -> Result<()> {
let mut clipboard = Clipboard::new().into_diagnostic()?;
let text = clipboard.get_text().into_diagnostic()?;
print!("{}", text);
Ok(())
}
pub fn read_from_stdin_and_set_clipboard<R: Read>(mut reader: R) -> Result<()> {
let mut buffer = String::new();
reader.read_to_string(&mut buffer).into_diagnostic()?;
set_clipboard_text(&buffer)
}