todoodoo/src/main.rs

104 lines
2.9 KiB
Rust
Raw Normal View History

2024-01-04 23:28:47 +01:00
use std::{
error::Error,
fmt::{self, Debug, Display},
fs::{File, OpenOptions},
io::{Read, Seek, SeekFrom, Write},
path::Path,
};
2024-01-04 16:36:41 +01:00
2024-01-05 13:16:08 +01:00
use eframe::egui::{self, Key, TextEdit, ViewportBuilder};
2024-01-04 23:28:47 +01:00
enum RunError {
HomeDir(homedir::GetHomeError),
NoHome,
OpenFile(std::io::Error),
EFrame(eframe::Error),
}
impl Debug for RunError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Display::fmt(self, f)
}
}
impl Display for RunError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::HomeDir(e) => f.write_fmt(format_args!("homedir error: {e}")),
Self::NoHome => f.write_fmt(format_args!("failed to find home directory")),
Self::OpenFile(e) => f.write_fmt(format_args!("error while opening todo.txt: {e}")),
Self::EFrame(e) => f.write_fmt(format_args!("eframe error: {e}")),
}
}
}
impl Error for RunError {}
fn main() -> Result<(), RunError> {
2024-01-04 16:36:41 +01:00
std::env::set_var("WINIT_UNIX_BACKEND", "wayland");
2024-01-04 23:28:47 +01:00
let home_dir = homedir::get_my_home()
.map_err(RunError::HomeDir)?
.ok_or(RunError::NoHome)?;
let todo_file = OpenOptions::new()
.create(true)
.read(true)
.write(true)
.append(false)
.open(Path::join(&home_dir, "todo.txt"))
.map_err(RunError::OpenFile)?;
2024-01-05 13:16:08 +01:00
let native_options = eframe::NativeOptions {
viewport: ViewportBuilder::default().with_app_id("todoodoo"),
..Default::default()
};
2024-01-04 23:28:47 +01:00
eframe::run_native(
"To-DooDoo",
2024-01-04 16:36:41 +01:00
native_options,
2024-01-04 23:28:47 +01:00
Box::new(|_cc| Box::new(ToDooDooApp::new(todo_file))),
)
.map_err(RunError::EFrame)?;
Ok(())
2024-01-04 16:36:41 +01:00
}
2024-01-04 23:28:47 +01:00
struct ToDooDooApp {
notes: String,
file: File,
}
impl ToDooDooApp {
fn new(mut file: File) -> Self {
let mut notes = String::with_capacity(
file.metadata()
.expect("file metadata")
.len()
.try_into()
.expect("file too big"),
);
file.read_to_string(&mut notes)
.expect("failed to read file");
Self { file, notes }
}
2024-01-04 16:36:41 +01:00
2024-01-04 23:28:47 +01:00
fn save(&mut self) {
self.file.set_len(0).expect("failed to truncate file");
self.file.seek(SeekFrom::Start(0)).expect("failed to seek");
self.file
.write_all(self.notes.as_bytes())
.expect("failed to write file");
self.file.flush().expect("failed to flush");
2024-01-04 16:36:41 +01:00
}
}
2024-01-04 23:28:47 +01:00
impl eframe::App for ToDooDooApp {
2024-01-04 16:36:41 +01:00
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
2024-01-04 23:28:47 +01:00
if ctx.input(|i| i.key_pressed(Key::S) && i.modifiers.command) {
self.save();
}
ui.add_sized(ui.available_size(), TextEdit::multiline(&mut self.notes));
2024-01-04 16:36:41 +01:00
});
}
2024-01-05 13:16:35 +01:00
fn save(&mut self, _storage: &mut dyn eframe::Storage) {
self.save();
}
2024-01-04 16:36:41 +01:00
}