nix-configs/programs/jrnl/src/md.rs

68 lines
1.7 KiB
Rust
Raw Normal View History

use chrono::{DateTime, FixedOffset};
use std::convert::identity;
2024-04-22 11:44:26 +02:00
pub trait ToMd {
fn to_md(&self) -> String;
}
#[derive(Debug)]
pub struct Doc<'src> {
pub entries: Vec<Entry<'src>>,
}
impl<'src> Doc<'src> {
// TODO: better parsing errors?
pub fn new(f: &'src str) -> Option<Self> {
let entries = f
.split("\n## ")
.map(|s| s.split_once("\n"))
.skip(1)
.filter_map(identity)
.map(|(title, content)| (title.split_once(": "), content))
.map(|(title, content)| {
if let Some((ts, title)) = title {
Some(Entry {
timestamp: DateTime::parse_from_rfc3339(ts).unwrap(),
title,
content: content.trim_matches('\n'),
})
} else {
None
}
})
.collect::<Vec<_>>();
entries.iter().all(|it| it.is_some()).then_some(Self {
entries: entries.into_iter().filter_map(identity).collect(),
})
}
}
2024-04-22 11:44:26 +02:00
impl ToMd for Doc<'_> {
fn to_md(&self) -> String {
let mut r = "# Journal\n\n".to_owned();
self.entries.iter().fold(r, |mut r, it| r + &it.to_md())
}
}
#[derive(Debug, Clone)]
pub struct Entry<'src> {
pub timestamp: DateTime<FixedOffset>,
pub title: &'src str,
pub content: &'src str,
}
2024-04-22 11:44:26 +02:00
impl ToMd for Entry<'_> {
fn to_md(&self) -> String {
format!(
"## {}: {}\n\n{}\n\n",
2024-04-22 21:25:29 +02:00
self.timestamp
.fixed_offset()
.to_rfc3339_opts(chrono::SecondsFormat::Secs, false),
self.title,
self.content
2024-04-22 11:44:26 +02:00
)
}
}