Files
inkr/src/util.rs

57 lines
1.4 KiB
Rust

use std::{fs::File, os::unix::fs::MetadataExt as _, sync::mpsc};
use chrono::{DateTime, Local};
use egui::Id;
use eyre::{Context, ContextCompat};
use rand::{Rng, rng};
pub fn random_id() -> Id {
Id::new(rng().random::<u64>())
}
/// An [mpsc::Sender] where the receiver is the GUI.
#[derive(Clone)]
pub struct GuiSender<T> {
tx: mpsc::Sender<T>,
ctx: egui::Context,
}
impl<T> GuiSender<T> {
pub fn new(tx: mpsc::Sender<T>, ctx: &egui::Context) -> Self {
Self {
tx,
ctx: ctx.clone(),
}
}
pub fn send(&self, t: T) -> Result<(), mpsc::SendError<T>> {
self.tx.send(t)?;
self.ctx.request_repaint();
Ok(())
}
}
#[track_caller]
pub fn log_error<T>(chain: eyre::Report, f: impl FnOnce() -> eyre::Result<T>) -> Option<T> {
f().map_err(|e| e.wrap_err(chain))
.inspect_err(|e| log::error!("{e}"))
.ok()
}
pub fn file_mtime(file: &File) -> eyre::Result<DateTime<Local>> {
(move || {
let meta = file.metadata().wrap_err("Failed to stat file")?;
let sec = meta.mtime();
let nsec = meta
.mtime_nsec()
.try_into()
.wrap_err("Nanoseconds overflowed")?;
DateTime::from_timestamp(sec, nsec)
.wrap_err("Bad timestamp")
.map(Into::into)
})()
.wrap_err("Failed to get file mtime")
}