start with notes program
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user