103 lines
2.8 KiB
Rust
103 lines
2.8 KiB
Rust
|
use std::collections::HashMap;
|
||
|
use std::path::Path;
|
||
|
use std::sync::mpsc::channel;
|
||
|
use std::time::Duration;
|
||
|
use std::{fs, io};
|
||
|
|
||
|
use notify::{
|
||
|
DebouncedEvent::{Create, NoticeRemove, NoticeWrite, Remove},
|
||
|
RecommendedWatcher, RecursiveMode, Watcher,
|
||
|
};
|
||
|
|
||
|
enum Type {
|
||
|
Tag = 5,
|
||
|
}
|
||
|
|
||
|
fn read_file(path: &Path) -> Result<HashMap<String, String>, io::Error> {
|
||
|
let content = fs::read_to_string(path)?;
|
||
|
let content = content.trim().split("\n").collect::<Vec<_>>();
|
||
|
|
||
|
println!("content: {}", content.join("\n"));
|
||
|
|
||
|
let mut fields = HashMap::new();
|
||
|
|
||
|
for j in 0..content.len() {
|
||
|
let i = content.len() - 1 - j;
|
||
|
let line = content[i];
|
||
|
|
||
|
if let Some(index) = line.find(":") {
|
||
|
let (key, value) = line.split_at(index);
|
||
|
// Remove the ":" character.
|
||
|
let value = value[1..].trim();
|
||
|
if key.len() > 0 && value.len() > 0 {
|
||
|
fields.insert(key.to_string(), value.to_string());
|
||
|
}
|
||
|
} else {
|
||
|
// First line without a metadata field! Reverse content, it's the markdown block.
|
||
|
let markdown = content[0..i]
|
||
|
.iter()
|
||
|
.map(|s| s.to_string())
|
||
|
.collect::<Vec<_>>()
|
||
|
.join("\n");
|
||
|
let markdown = markdown.trim();
|
||
|
fields.insert("markdown_content".to_string(), markdown.to_string());
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
println!(
|
||
|
"Extracted content of {} ({} fields)",
|
||
|
fields["id"],
|
||
|
fields.len()
|
||
|
);
|
||
|
|
||
|
Ok(fields)
|
||
|
}
|
||
|
|
||
|
fn main() -> Result<(), io::Error> {
|
||
|
let mut num_files = 0;
|
||
|
let mut files = HashMap::new();
|
||
|
|
||
|
for entry in fs::read_dir("./assets/notes")? {
|
||
|
let dir_entry = entry?;
|
||
|
if !dir_entry.file_type()?.is_file() {
|
||
|
continue;
|
||
|
}
|
||
|
let path = dir_entry.path();
|
||
|
let read_file = read_file(&path)?;
|
||
|
files.insert(path, read_file);
|
||
|
num_files += 1;
|
||
|
}
|
||
|
|
||
|
println!("Found {} files.", num_files);
|
||
|
|
||
|
println!("Now listening to disk events...");
|
||
|
|
||
|
let (tx, rx) = channel();
|
||
|
let mut watcher: RecommendedWatcher = Watcher::new(tx, Duration::from_secs(2)).unwrap();
|
||
|
|
||
|
watcher
|
||
|
.watch("./assets/", RecursiveMode::Recursive)
|
||
|
.unwrap();
|
||
|
|
||
|
loop {
|
||
|
match rx.recv() {
|
||
|
Ok(evt) => {
|
||
|
match &evt {
|
||
|
NoticeWrite(path) | Create(path) => {
|
||
|
files.insert(path.clone(), read_file(path)?);
|
||
|
}
|
||
|
NoticeRemove(path) | Remove(path) => {
|
||
|
files.remove(path);
|
||
|
}
|
||
|
_ => {}
|
||
|
}
|
||
|
println!("{:?}", evt);
|
||
|
}
|
||
|
Err(e) => println!("watch error: {:?}", e),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Ok(())
|
||
|
}
|