Encapsulate command executions
Signed-off-by: Trivernis <trivernis@protonmail.com>i18n
parent
247659b7ba
commit
2266b10a7b
@ -0,0 +1,54 @@
|
||||
use crate::crash;
|
||||
use std::error::Error;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::io;
|
||||
|
||||
pub type AppResult<T> = Result<T, AppError>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum AppError {
|
||||
Io(std::io::Error),
|
||||
Other(String),
|
||||
}
|
||||
|
||||
impl Display for AppError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
AppError::Io(io) => Display::fmt(io, f),
|
||||
AppError::Other(s) => Display::fmt(s, f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for AppError {}
|
||||
|
||||
impl From<io::Error> for AppError {
|
||||
fn from(e: io::Error) -> Self {
|
||||
Self::Io(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for AppError {
|
||||
fn from(string: String) -> Self {
|
||||
Self::Other(string)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for AppError {
|
||||
fn from(string: &str) -> Self {
|
||||
Self::from(string.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
pub trait SilentUnwrap<T> {
|
||||
fn silent_unwrap(self) -> T;
|
||||
}
|
||||
|
||||
impl<T> SilentUnwrap<T> for AppResult<T> {
|
||||
fn silent_unwrap(self) -> T {
|
||||
match self {
|
||||
Ok(val) => val,
|
||||
Err(_) => crash("an error occurred", 1),
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
use crate::error::{AppError, AppResult};
|
||||
use crate::internal::uwu_enabled;
|
||||
use crate::uwu;
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::process::{ChildStderr, ChildStdout, Command, Stdio};
|
||||
|
||||
/// Executes a makepkg command
|
||||
#[inline]
|
||||
pub fn makepkg<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(args: I) -> AppResult<String> {
|
||||
run_command("makepkg", args)
|
||||
}
|
||||
|
||||
/// Executes a git command
|
||||
#[inline]
|
||||
pub fn git<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(args: I) -> AppResult<String> {
|
||||
run_command("git", args)
|
||||
}
|
||||
|
||||
/// Executes a bash command
|
||||
#[inline]
|
||||
pub fn bash<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(args: I) -> AppResult<String> {
|
||||
run_command("bash", args)
|
||||
}
|
||||
|
||||
/// Runs pacman with sudo
|
||||
pub fn sudo_pacman<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(args: I) -> AppResult<String> {
|
||||
let mut pacman_args = args
|
||||
.into_iter()
|
||||
.map(|i: S| OsString::from(i.as_ref()))
|
||||
.collect::<Vec<OsString>>();
|
||||
let mut sudo_args = vec![OsString::from("pacman")];
|
||||
sudo_args.append(&mut pacman_args);
|
||||
sudo(sudo_args)
|
||||
}
|
||||
|
||||
/// Executes a pacman command
|
||||
#[inline]
|
||||
pub fn pacman<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(args: I) -> AppResult<String> {
|
||||
run_command("pacman", args)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn sudo<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(args: I) -> AppResult<String> {
|
||||
run_command("sudo", args)
|
||||
}
|
||||
|
||||
/// Runs a command and parses its output as string
|
||||
fn run_command<S1: AsRef<OsStr>, I: IntoIterator<Item = S2>, S2: AsRef<OsStr>>(
|
||||
command: S1,
|
||||
args: I,
|
||||
) -> AppResult<String> {
|
||||
let mut child = Command::new(command)
|
||||
.args(args)
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()?;
|
||||
let stdout = child.stdout.as_mut().unwrap();
|
||||
let stderr = child.stderr.as_mut().unwrap();
|
||||
let stdout_str = read_stdout(stdout)?;
|
||||
let stderr_str = read_stderr(stderr)?;
|
||||
|
||||
let status = child.wait()?;
|
||||
if status.success() {
|
||||
Ok(stdout_str)
|
||||
} else {
|
||||
Err(AppError::from(stderr_str))
|
||||
}
|
||||
}
|
||||
|
||||
fn read_stdout(stdout: &mut ChildStdout) -> AppResult<String> {
|
||||
let mut stdout_str = String::new();
|
||||
let stdout_reader = BufReader::new(stdout);
|
||||
|
||||
for line in stdout_reader.lines() {
|
||||
let line = line?;
|
||||
if uwu_enabled() {
|
||||
println!("{}", uwu!(&*line))
|
||||
} else {
|
||||
println!("{}", &line);
|
||||
}
|
||||
stdout_str.push_str(&line);
|
||||
stdout_str.push_str("\n");
|
||||
}
|
||||
|
||||
Ok(stdout_str)
|
||||
}
|
||||
|
||||
fn read_stderr(stderr: &mut ChildStderr) -> AppResult<String> {
|
||||
let mut stderr_str = String::new();
|
||||
let stderr_reader = BufReader::new(stderr);
|
||||
|
||||
for line in stderr_reader.lines() {
|
||||
let line = line?;
|
||||
if uwu_enabled() {
|
||||
eprintln!("{}", uwu!(&line))
|
||||
} else {
|
||||
eprintln!("{}", &line);
|
||||
}
|
||||
stderr_str.push_str(&line);
|
||||
stderr_str.push_str("\n");
|
||||
}
|
||||
|
||||
Ok(stderr_str)
|
||||
}
|
Loading…
Reference in New Issue