start with notes program

This commit is contained in:
2026-01-22 21:02:28 +01:00
parent a699022812
commit 1967a3e1d6
4 changed files with 292 additions and 16 deletions

View File

@@ -1,33 +1,120 @@
use std::fs;
use ron;
use serde::{Serialize, Deserialize};
use chrono;
use chrono::{self, NaiveDate, Local};
use clap::Parser;
use serde::{Deserialize, Serialize};
use std::{
collections::HashSet, fmt::Write as _, fs::{File, OpenOptions}, io::{BufRead, BufReader, Read, Seek, Write as _}, path::{Path, PathBuf}
};
#[derive(Parser, Debug)]
#[command(version, about, long_about = None)]
struct Args {
notes: PathBuf,
patterns: Option<PathBuf>,
}
#[derive(Serialize, Deserialize, Debug)]
enum Pattern {
Yearly { doy: u32 },
MonthlyOpt { dom: u32, months: Vec<chrono::Month> },
Monthly { dom: u32 },
Weekly { dow: u32 },
Yearly {
doy: u32,
},
MonthlyOpt {
dom: u32,
months: Vec<chrono::Month>,
},
Monthly {
dom: u32,
},
Weekly {
dow: u32,
},
Daily,
}
#[derive(Serialize, Deserialize, Debug)]
struct Position {
name: String,
pattern: Pattern
pattern: Pattern,
}
fn parse_patterns() {
let f = fs::read_to_string("data/patterns.ron").expect("file should exist");
let patterns: Vec<Position> = ron::from_str(&f).expect("file should follow proper ron syntax");
dbg!(patterns);
}
fn update_notes(notes_path: &Path) {
let mut file = OpenOptions::new().read(true).write(true).open(notes_path).expect("file should exist");
let mut bufreader = BufReader::new(&file);
let mut linebuf = String::new();
let mut all_lines = String::new();
let mut latest_date = NaiveDate::MIN;
let mut lines_with_duplicates: Vec<usize> = Vec::new();
// Find todo-type lines
while let Ok(n) = bufreader.read_line(&mut linebuf) {
if n == 0 {
break;
}
let trimmed_str = linebuf.trim();
let trimmed_bytes = trimmed_str.as_bytes();
let Some(sub) = trimmed_bytes.get(0..5) else { continue; };
println!("cur line is {:?}. Sub is {:?}", trimmed_str, sub);
if sub == b"- [ ]" {
all_lines.push_str(&linebuf);
} else if trimmed_bytes.get(0) == Some(&b'#') {
if let Ok(date) = NaiveDate::parse_from_str(trimmed_str.get(1..).unwrap(), "%Y-%m-%d") {
if date > latest_date {
latest_date = date;
}
}
}
linebuf.clear();
}
// Find duplicates
let mut todos_hashset: HashSet<&str> = HashSet::new();
for (idx, line) in all_lines.split("\n").enumerate() {
if !todos_hashset.insert(line) {
lines_with_duplicates.push(idx);
}
}
// Prepare buffer
let res1 = bufreader.seek(std::io::SeekFrom::End(-2));
let mut last_two_bytes = [0u8, 0u8];
let res2 = bufreader.read_exact(&mut last_two_bytes);
if last_two_bytes != *b"\n\n" {
write!(linebuf, "\n");
}
let today = Local::now().date_naive();
if latest_date < today {
writeln!(linebuf, "# {}", today);
}
fn parse_notes() {
let mut cur = 0;
for (idx, line) in all_lines.split("\n").enumerate() {
if cur < lines_with_duplicates.len() && lines_with_duplicates[cur] == idx {
cur += 1;
} else {
writeln!(linebuf, "{line}");
}
}
println!("{:?}", file.write_all(linebuf.as_bytes()));
// TODO: Handle case if today already exists
// TODO: Dont put once-open but now closed todos in
// Opt: Create new date for today
// Put all open todos into today
}
fn parse_patterns(notes_path: &Path, patterns_path: &Path) {
// Put all patternized todos into today
}
fn main() {
parse_patterns();
let args = Args::parse();
update_notes(&args.notes);
if let Some(patterns_path) = args.patterns {
parse_patterns(&args.notes, &patterns_path);
}
}