use std::{
borrow::Cow,
io::{Result, Write},
process::{self, Stdio},
};
#[allow(unused_macros)]
macro_rules! log {
($e:expr) => {{
if cfg!(debug_assertions) {
if let Ok(mut file) = std::fs::OpenOptions::new()
.append(true)
.create(true)
.open("phetch.log")
{
use std::io::prelude::*;
file.write($e.as_ref()).unwrap();
file.write(b"\n").unwrap();
}
}
}};
($e:expr, $($y:expr),*) => {
if cfg!(debug_assertions) {
log!(format!($e, $($y),*));
}
};
}
macro_rules! error {
($e:expr) => {
std::io::Error::new(std::io::ErrorKind::Other, $e)
};
($e:expr, $($y:expr),*) => {
error!(format!($e, $($y),*))
};
}
pub fn human_bytes(bytes: usize) -> String {
let (count, tag) = if bytes < 1000 {
(bytes, " bytes")
} else if bytes < 1_000_000 {
(bytes / 1000, "Kb")
} else if bytes < 1_000_000_000 {
(bytes / 1_000_000, "Mb")
} else {
(bytes / 1_000_000_000, "Gb")
};
format!("{}{}", count, tag)
}
pub fn copy_to_clipboard(data: &str) -> Result<()> {
#[cfg(target_os = "macos")]
let mut cmd = process::Command::new("pbcopy");
#[cfg(not(target_os = "macos"))]
let mut cmd = process::Command::new("xclip");
#[cfg(not(target_os = "macos"))]
let cmd = cmd.args(&["-sel", "clip"]);
cmd.stdin(Stdio::piped())
.spawn()
.and_then(|mut child| {
let child_stdin = child.stdin.as_mut().unwrap();
child_stdin.write_all(data.as_bytes())
})
.map_err(|e| error!("Clipboard error: {}", e))
}
pub fn open_external(url: &str) -> Result<()> {
#[cfg(target_os = "macos")]
let cmd = "open";
#[cfg(not(target_os = "macos"))]
let cmd = "xdg-open";
let output = process::Command::new(cmd)
.arg(url)
.output()
.map_err(|e| error!("`open` error: {}", e))?;
if output.stderr.is_empty() {
Ok(())
} else {
Err(error!(
"`open` error: {}",
String::from_utf8_lossy(&output.stderr).trim_end()
))
}
}
pub fn open_media(program: &str, url: &str) -> Result<()> {
use {crate::terminal, std::io};
let url = if program.ends_with("mpv") {
Cow::from(url.replace("/;/", "/9/").replace("/s/", "/9/"))
} else {
Cow::from(url)
};
let url = if let Some(idx) = url.find("URL:") {
url.split_at(idx).1.trim_start_matches("URL:")
} else {
&url
};
let errfn = |e| {
terminal::enable_raw_mode().unwrap();
error!("Media player error: {}", e)
};
let mut stdout = io::stdout();
write!(stdout, "{}{}", terminal::ClearAll, terminal::Goto(1, 1))?;
stdout.flush()?;
terminal::disable_raw_mode()?;
let mut cmd = process::Command::new(program)
.arg(url)
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.spawn()
.map_err(errfn)?;
cmd.wait().map_err(errfn)?;
terminal::enable_raw_mode()?;
Ok(())
}