Replace common functionality with rust implementation
This commit is contained in:
87
mgr/src/bin/client.rs
Normal file
87
mgr/src/bin/client.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
#![expect(
|
||||
clippy::print_stderr,
|
||||
clippy::print_stdout,
|
||||
reason = "output is fine for cli"
|
||||
)]
|
||||
|
||||
use std::{
|
||||
env,
|
||||
io::{self, Read as _},
|
||||
net,
|
||||
os::unix::net::UnixStream,
|
||||
process, str,
|
||||
};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
use mgr::{
|
||||
Action,
|
||||
cli::{self, CliCommand as _, ParseError},
|
||||
wire::{client, socket},
|
||||
};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum Error {
|
||||
#[error(transparent)]
|
||||
Io(#[from] io::Error),
|
||||
#[error(transparent)]
|
||||
Socket(#[from] socket::Error),
|
||||
#[error(transparent)]
|
||||
Send(#[from] client::SendError),
|
||||
#[error(transparent)]
|
||||
CliParse(#[from] cli::ParseError),
|
||||
#[error("response is not valid utf8: {0}")]
|
||||
ResponseNonUtf8(#[from] str::Utf8Error),
|
||||
}
|
||||
|
||||
enum MainResult {
|
||||
Success,
|
||||
Failure(Error),
|
||||
}
|
||||
|
||||
impl process::Termination for MainResult {
|
||||
fn report(self) -> process::ExitCode {
|
||||
match self {
|
||||
Self::Success => process::ExitCode::SUCCESS,
|
||||
Self::Failure(e) => {
|
||||
eprintln!("Error: {e}");
|
||||
process::ExitCode::FAILURE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() -> MainResult {
|
||||
fn inner() -> Result<(), Error> {
|
||||
let mut args = env::args().skip(1);
|
||||
|
||||
let socket = socket::get_socket_path()?;
|
||||
let mut stream = UnixStream::connect(socket)?;
|
||||
|
||||
let action =
|
||||
Action::parse_str(args.next().ok_or(ParseError::MissingAction)?.as_str(), args)?;
|
||||
|
||||
action.send(&mut stream)?;
|
||||
|
||||
stream.shutdown(net::Shutdown::Write)?;
|
||||
|
||||
let response = {
|
||||
let mut buf = Vec::new();
|
||||
stream.read_to_end(&mut buf)?;
|
||||
let response = str::from_utf8(&buf)?.to_owned();
|
||||
drop(stream);
|
||||
response
|
||||
};
|
||||
|
||||
if !response.is_empty() {
|
||||
println!("{response}");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
match inner() {
|
||||
Ok(()) => MainResult::Success,
|
||||
Err(e) => MainResult::Failure(e),
|
||||
}
|
||||
}
|
||||
105
mgr/src/bin/main.rs
Executable file
105
mgr/src/bin/main.rs
Executable file
@@ -0,0 +1,105 @@
|
||||
#![expect(
|
||||
clippy::print_stderr,
|
||||
clippy::print_stdout,
|
||||
reason = "output is fine for cli"
|
||||
)]
|
||||
|
||||
use std::{env, process};
|
||||
|
||||
use thiserror::Error;
|
||||
use tracing::Level;
|
||||
|
||||
use mgr::{
|
||||
self, Action, Exec as _,
|
||||
cli::{CliCommand as _, ParseError},
|
||||
};
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum Error {
|
||||
#[error(transparent)]
|
||||
Power(#[from] mgr::power::Error),
|
||||
#[error(transparent)]
|
||||
Dmenu(#[from] mgr::dmenu::Error),
|
||||
#[error(transparent)]
|
||||
Server(#[from] mgr::wire::server::Error),
|
||||
#[error(transparent)]
|
||||
Presentation(#[from] mgr::present::Error),
|
||||
#[error(transparent)]
|
||||
Exec(#[from] mgr::ExecError),
|
||||
#[error(transparent)]
|
||||
ParseParse(#[from] ParseError),
|
||||
#[error(transparent)]
|
||||
Tracing(#[from] tracing::dispatcher::SetGlobalDefaultError),
|
||||
}
|
||||
|
||||
enum MainResult {
|
||||
Success,
|
||||
Failure(Error),
|
||||
}
|
||||
|
||||
impl process::Termination for MainResult {
|
||||
fn report(self) -> process::ExitCode {
|
||||
match self {
|
||||
Self::Success => process::ExitCode::SUCCESS,
|
||||
Self::Failure(e) => {
|
||||
eprintln!("Error: {e}");
|
||||
process::ExitCode::FAILURE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for MainResult {
|
||||
fn from(value: Error) -> Self {
|
||||
Self::Failure(value)
|
||||
}
|
||||
}
|
||||
|
||||
fn init_tracing() -> Result<(), Error> {
|
||||
tracing::subscriber::set_global_default(
|
||||
tracing_subscriber::fmt()
|
||||
.with_max_level(Level::DEBUG)
|
||||
.event_format(
|
||||
tracing_subscriber::fmt::format()
|
||||
.with_ansi(false)
|
||||
.with_target(false)
|
||||
.compact(),
|
||||
)
|
||||
.finish(),
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() -> MainResult {
|
||||
fn inner() -> Result<(), Error> {
|
||||
init_tracing()?;
|
||||
|
||||
let mut args = env::args().skip(1);
|
||||
|
||||
match args.next().ok_or(ParseError::MissingAction)?.as_str() {
|
||||
"serve" => {
|
||||
mgr::wire::server::run()?;
|
||||
Ok(())
|
||||
}
|
||||
"run" => {
|
||||
let action = Action::parse_str(
|
||||
args.next().ok_or(ParseError::MissingAction)?.as_str(),
|
||||
args,
|
||||
)?;
|
||||
if let Some(output) = action.execute()? {
|
||||
println!("{output}");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
input => Err(ParseError::UnknownAction {
|
||||
action: input.to_owned(),
|
||||
}
|
||||
.into()),
|
||||
}
|
||||
}
|
||||
|
||||
match inner() {
|
||||
Ok(()) => MainResult::Success,
|
||||
Err(e) => MainResult::Failure(e),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user