added cli options

This commit is contained in:
Parker TenBroeck 2026-03-11 13:23:28 -04:00
parent defbd88adf
commit 00dcf6d3f8
4 changed files with 119 additions and 11 deletions

View file

@ -37,7 +37,7 @@ struct Handler {
impl Handler {
fn local(socket: WebSocket, build: PathBuf, src: PathBuf) -> Self {
fn local(socket: WebSocket, build: PathBuf, src: PathBuf, refresh_time: Duration) -> Self {
let (sender, receiver) = socket.split();
Self {
sender,
@ -45,7 +45,7 @@ impl Handler {
build_dir: build,
src_dir: src,
process: None,
refresh_time: Duration::from_millis(30),
refresh_time,
}
}
@ -207,6 +207,6 @@ impl Handler {
}
}
pub async fn ws_handler(socket: WebSocket) {
Handler::local(socket, "../target".into(), "../src".into()).run().await;
pub async fn ws_handler(socket: WebSocket, refresh_time: Duration) {
Handler::local(socket, "../target".into(), "../src".into(), refresh_time).run().await;
}

View file

@ -6,7 +6,10 @@ use axum::{
routing::get,
};
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use std::{
net::{IpAddr, SocketAddr},
time::Duration,
};
pub mod build;
pub mod run;
@ -39,8 +42,73 @@ async fn not_found() -> impl IntoResponse {
(StatusCode::NOT_FOUND, "not found")
}
#[derive(Clone, Copy, Debug)]
struct Config {
ip: IpAddr,
port: u16,
update_ms: u64,
}
impl Default for Config {
fn default() -> Self {
Self {
ip: IpAddr::from([127, 0, 0, 1]),
port: 8080,
update_ms: 30,
}
}
}
fn parse_config_from_args() -> Result<Config, String> {
let mut cfg = Config::default();
let mut args = std::env::args().skip(1);
while let Some(arg) = args.next() {
match arg.as_str() {
"--" => break,
"--ip" => {
let value = args.next().ok_or("missing value for --ip")?;
cfg.ip = value
.parse::<IpAddr>()
.map_err(|err| format!("invalid --ip `{value}`: {err}"))?;
}
"--port" => {
let value = args.next().ok_or("missing value for --port")?;
cfg.port = value
.parse::<u16>()
.map_err(|err| format!("invalid --port `{value}`: {err}"))?;
}
"--update-ms" => {
let value = args.next().ok_or("missing value for --update-ms")?;
cfg.update_ms = value
.parse::<u64>()
.map_err(|err| format!("invalid --update-ms `{value}`: {err}"))?;
}
"--help" | "-h" => {
return Err("usage: relay [--ip <ip>] [--port <port>] [--update-ms <ms>]".into());
}
_ => {
return Err(format!(
"unknown argument `{arg}`\nusage: relay [--ip <ip>] [--port <port>] [--update-ms <ms>]"
));
}
}
}
Ok(cfg)
}
#[tokio::main]
async fn main() {
let cfg = match parse_config_from_args() {
Ok(cfg) => cfg,
Err(msg) => {
eprintln!("{msg}");
std::process::exit(2);
}
};
let update_interval = Duration::from_millis(cfg.update_ms);
let app = Router::new()
.route("/", get(serve_index))
.route("/index.html", get(serve_index))
@ -48,15 +116,34 @@ async fn main() {
.route("/app.js", get(serve_app_js))
.route(
"/ws/remote",
get(|ws: WebSocketUpgrade| async move { ws.on_upgrade(local::ws_handler) }),
get(move |ws: WebSocketUpgrade| {
let update_interval = update_interval;
async move {
ws.on_upgrade(move |socket| remote::ws_handler(socket, update_interval))
}
}),
)
.route(
"/ws/local",
get(|ws: WebSocketUpgrade| async move { ws.on_upgrade(remote::ws_handler) }),
get(move |ws: WebSocketUpgrade| {
let update_interval = update_interval;
async move {
ws.on_upgrade(move |socket| local::ws_handler(socket, update_interval))
}
}),
)
.route(
"/ws",
get(move |ws: WebSocketUpgrade| {
let update_interval = update_interval;
async move {
ws.on_upgrade(move |socket| remote::ws_handler(socket, update_interval))
}
}),
)
.fallback(get(not_found));
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
let addr = SocketAddr::new(cfg.ip, cfg.port);
println!("Open UI: http://{}/", addr);
axum::serve(tokio::net::TcpListener::bind(addr).await.unwrap(), app)

View file

@ -11,7 +11,7 @@ use tokio::{
use crate::{ClientMsg, HResult, ServerMsg, build, run};
pub async fn ws_handler(socket: WebSocket) {
pub async fn ws_handler(socket: WebSocket, refresh_time: Duration) {
let (mut sender, mut receiver) = socket.split();
let files = if let Some(Ok(Message::Text(msg))) = receiver.next().await
@ -113,7 +113,7 @@ pub async fn ws_handler(socket: WebSocket) {
}
_ = tokio::time::sleep_until(print_deadline) => {
use tokio::io::AsyncWriteExt;
print_deadline += Duration::from_millis(30);
print_deadline += refresh_time;
process.stdin.write_all("\n".as_bytes()).await?;
}
}
@ -127,4 +127,4 @@ pub async fn ws_handler(socket: WebSocket) {
_ = sender.send(Message::Text(format!("{err}").into())).await;
},
}
}
}