2025-06-08 22:24:14 -05:00
|
|
|
// client/src/main.rs
|
|
|
|
|
|
2025-06-01 16:04:00 -05:00
|
|
|
#![forbid(unsafe_code)]
|
|
|
|
|
|
2025-06-01 14:46:12 -05:00
|
|
|
use anyhow::Result;
|
2025-06-16 17:54:47 -05:00
|
|
|
use std::{env, fs::OpenOptions, path::Path};
|
|
|
|
|
use tracing_appender::non_blocking;
|
|
|
|
|
use tracing_appender::non_blocking::WorkerGuard;
|
|
|
|
|
use tracing_subscriber::{filter::EnvFilter, fmt, prelude::*};
|
2025-06-01 13:31:22 -05:00
|
|
|
|
2025-06-23 07:18:26 -05:00
|
|
|
use lesavka_client::LesavkaClientApp;
|
2025-06-21 05:21:57 -05:00
|
|
|
|
2025-06-25 16:23:50 -05:00
|
|
|
fn ensure_runtime_dir() {
|
|
|
|
|
if env::var_os("XDG_RUNTIME_DIR").is_none() {
|
|
|
|
|
eprintln!(
|
|
|
|
|
"Error: $XDG_RUNTIME_DIR is not set. \
|
|
|
|
|
Launch the client from a regular desktop session or export it manually, \
|
|
|
|
|
e.g. `export XDG_RUNTIME_DIR=/run/user/$(id -u)`."
|
|
|
|
|
);
|
|
|
|
|
std::process::exit(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-26 14:05:23 -05:00
|
|
|
#[tokio::main(flavor = "current_thread")]
|
2025-06-01 14:46:12 -05:00
|
|
|
async fn main() -> Result<()> {
|
2025-06-25 16:23:50 -05:00
|
|
|
ensure_runtime_dir();
|
|
|
|
|
|
2025-06-16 17:54:47 -05:00
|
|
|
/*------------- common filter & stderr layer ------------------------*/
|
|
|
|
|
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| {
|
|
|
|
|
EnvFilter::new(
|
2025-06-23 07:18:26 -05:00
|
|
|
"lesavka_client=trace,\
|
|
|
|
|
lesavka_server=trace,\
|
2025-06-16 17:54:47 -05:00
|
|
|
tonic=debug,\
|
|
|
|
|
h2=debug,\
|
|
|
|
|
tower=debug",
|
|
|
|
|
)
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let stderr_layer = fmt::layer()
|
|
|
|
|
.with_target(true)
|
|
|
|
|
.with_thread_ids(true)
|
|
|
|
|
.with_file(true);
|
2025-06-16 00:05:39 -05:00
|
|
|
|
2025-06-26 14:05:23 -05:00
|
|
|
let dev_mode = env::var("LESAVKA_DEV_MODE").is_ok();
|
2025-06-16 17:54:47 -05:00
|
|
|
let mut _guard: Option<WorkerGuard> = None; // keep guard alive
|
2025-06-08 12:47:11 -05:00
|
|
|
|
2025-06-16 17:54:47 -05:00
|
|
|
/*------------- subscriber setup -----------------------------------*/
|
2025-06-08 12:47:11 -05:00
|
|
|
if dev_mode {
|
2025-06-23 07:18:26 -05:00
|
|
|
let log_path = Path::new("/tmp").join("lesavka-client.log");
|
2025-06-16 17:54:47 -05:00
|
|
|
|
2025-06-28 15:45:35 -05:00
|
|
|
// file → non-blocking writer (+ guard)
|
2025-06-08 12:47:11 -05:00
|
|
|
let file = OpenOptions::new()
|
|
|
|
|
.create(true)
|
2025-06-17 23:42:24 -05:00
|
|
|
.write(true)
|
2025-06-18 01:41:11 -05:00
|
|
|
// .truncate(true)
|
2025-06-16 17:54:47 -05:00
|
|
|
.open(&log_path)?;
|
|
|
|
|
let (file_writer, guard) = non_blocking(file);
|
|
|
|
|
_guard = Some(guard);
|
|
|
|
|
|
|
|
|
|
let file_layer = fmt::layer()
|
|
|
|
|
.with_writer(file_writer)
|
|
|
|
|
.with_ansi(false)
|
|
|
|
|
.with_target(true)
|
|
|
|
|
.with_level(true);
|
|
|
|
|
|
|
|
|
|
tracing_subscriber::registry()
|
|
|
|
|
.with(env_filter)
|
|
|
|
|
.with(stderr_layer)
|
|
|
|
|
.with(file_layer)
|
|
|
|
|
.init();
|
|
|
|
|
|
2025-06-30 15:45:37 -05:00
|
|
|
tracing::info!("📜 lesavka-client running in DEV mode → {}", log_path.display());
|
2025-06-08 12:47:11 -05:00
|
|
|
} else {
|
2025-06-16 17:54:47 -05:00
|
|
|
tracing_subscriber::registry()
|
|
|
|
|
.with(env_filter)
|
|
|
|
|
.with(stderr_layer)
|
|
|
|
|
.init();
|
2025-06-08 12:47:11 -05:00
|
|
|
}
|
2025-06-06 00:21:20 -05:00
|
|
|
|
2025-06-16 17:54:47 -05:00
|
|
|
/*------------- run the actual application -------------------------*/
|
2025-06-23 07:18:26 -05:00
|
|
|
let mut app = LesavkaClientApp::new()?;
|
2025-06-08 04:11:58 -05:00
|
|
|
app.run().await
|
2025-06-16 17:54:47 -05:00
|
|
|
}
|