Build native UI shell foundation

This commit is contained in:
2026-07-04 10:41:51 +02:00
parent 89a99582a5
commit 6bcfc534a0
34 changed files with 1998 additions and 794 deletions

View File

@@ -1,8 +1,17 @@
use std::{path::Path, sync::OnceLock};
use std::{
fs::{self, OpenOptions},
io::{self, Write},
path::{Path, PathBuf},
sync::OnceLock,
};
use anyhow::Result;
use tracing_subscriber::{fmt, layer::SubscriberExt, EnvFilter};
const LOG_FILE: &str = "vnidrop.log";
const MAX_LOG_BYTES: u64 = 1_048_576;
const MAX_LOG_FILES: usize = 5;
static LOG_GUARD: OnceLock<tracing_appender::non_blocking::WorkerGuard> = OnceLock::new();
pub(crate) fn init_logging(app_data_dir: &Path) -> Result<()> {
@@ -11,9 +20,9 @@ pub(crate) fn init_logging(app_data_dir: &Path) -> Result<()> {
}
let log_dir = app_data_dir.join("logs");
std::fs::create_dir_all(&log_dir)?;
let file_appender = tracing_appender::rolling::daily(log_dir, "vnidrop.log");
let (writer, guard) = tracing_appender::non_blocking(file_appender);
fs::create_dir_all(&log_dir)?;
let writer = SizeRotatingWriter::new(log_dir, MAX_LOG_BYTES, MAX_LOG_FILES);
let (writer, guard) = tracing_appender::non_blocking(writer);
let filter = EnvFilter::try_from_default_env()
.unwrap_or_else(|_| EnvFilter::new("vnidrop=debug,iroh=info,iroh_blobs=info,warn"));
@@ -27,3 +36,71 @@ pub(crate) fn init_logging(app_data_dir: &Path) -> Result<()> {
Ok(())
}
struct SizeRotatingWriter {
log_dir: PathBuf,
max_bytes: u64,
max_files: usize,
}
impl SizeRotatingWriter {
fn new(log_dir: PathBuf, max_bytes: u64, max_files: usize) -> Self {
Self {
log_dir,
max_bytes,
max_files,
}
}
fn active_path(&self) -> PathBuf {
self.log_dir.join(LOG_FILE)
}
fn rotated_path(&self, index: usize) -> PathBuf {
self.log_dir.join(format!("vnidrop.{index}.log"))
}
fn rotate_if_needed(&self, incoming_bytes: usize) -> io::Result<()> {
fs::create_dir_all(&self.log_dir)?;
let active = self.active_path();
let current_size = active
.metadata()
.map(|metadata| metadata.len())
.unwrap_or(0);
if current_size == 0 || current_size + incoming_bytes as u64 <= self.max_bytes {
return Ok(());
}
if self.max_files == 0 {
let _ = fs::remove_file(active);
return Ok(());
}
let _ = fs::remove_file(self.rotated_path(self.max_files));
for index in (1..self.max_files).rev() {
let source = self.rotated_path(index);
if source.exists() {
let _ = fs::rename(source, self.rotated_path(index + 1));
}
}
if active.exists() {
let _ = fs::rename(active, self.rotated_path(1));
}
Ok(())
}
}
impl Write for SizeRotatingWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.rotate_if_needed(buf.len())?;
let mut file = OpenOptions::new()
.create(true)
.append(true)
.open(self.active_path())?;
file.write(buf)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}