1use std::path::Path;
4
5use chrono::NaiveDate;
6
7use crate::txn::atomic_write;
8
9pub const TIMESTAMP_FIELDS: &[&str] = &["created", "modified"];
10
11pub fn stamp_file(
12 path: &Path,
13 now: Option<NaiveDate>,
14) -> crate::errors::Result<StampResult> {
15 let today = now
16 .unwrap_or_else(|| chrono::Local::now().date_naive())
17 .format("%Y-%m-%d")
18 .to_string();
19
20 let text = std::fs::read_to_string(path)?;
21 let lines: Vec<&str> = text.split('\n').collect();
22
23 if lines.is_empty() || lines[0].trim() != "---" {
24 return Ok(StampResult {
25 created_set: false,
26 modified_updated: false,
27 });
28 }
29
30 let mut end_idx = None;
31 for i in 1..lines.len() {
32 if lines[i].trim() == "---" {
33 end_idx = Some(i);
34 break;
35 }
36 }
37
38 let end_idx = match end_idx {
39 Some(i) => i,
40 None => {
41 return Ok(StampResult {
42 created_set: false,
43 modified_updated: false,
44 });
45 }
46 };
47
48 let mut fm_lines: Vec<String> = lines[1..end_idx]
49 .iter()
50 .map(|s| s.to_string())
51 .collect();
52
53 let mut created_idx = None;
54 let mut modified_idx = None;
55 for (i, line) in fm_lines.iter().enumerate() {
56 let stripped = line.trim_start();
57 if stripped.starts_with("created:") || stripped.starts_with("created :") {
58 created_idx = Some(i);
59 } else if stripped.starts_with("modified:") || stripped.starts_with("modified :") {
60 modified_idx = Some(i);
61 }
62 }
63
64 let mut created_set = false;
65 if created_idx.is_none() {
66 fm_lines.push(format!("created: \"{}\"", today));
67 created_set = true;
68 }
69
70 if let Some(idx) = modified_idx {
71 fm_lines[idx] = format!("modified: \"{}\"", today);
72 } else {
73 fm_lines.push(format!("modified: \"{}\"", today));
74 }
75
76 let mut new_lines: Vec<String> = vec!["---".to_string()];
77 new_lines.extend(fm_lines);
78 new_lines.push("---".to_string());
79 for line in &lines[end_idx + 1..] {
80 new_lines.push(line.to_string());
81 }
82
83 atomic_write(path, &new_lines.join("\n"))?;
84
85 Ok(StampResult {
86 created_set,
87 modified_updated: true,
88 })
89}
90
91#[derive(Debug)]
92pub struct StampResult {
93 pub created_set: bool,
94 pub modified_updated: bool,
95}