use std::path::{Path, PathBuf};
use std::{collections::HashMap, fs};
use ignore::WalkBuilder;
use log::error;
use crate::model::{Content, State};
pub fn write_file(key: &String, content: &Content, to: &Path) -> std::io::Result<()> {
fs::write(to.join(format!("{}.md", key)), content.as_str())
}
pub fn new_for_path(base_path: &PathBuf) -> State {
if !base_path.exists() {
error!("path doesn't exist");
return State::new();
}
WalkBuilder::new(base_path)
.follow_links(false)
.hidden(true)
.require_git(false)
.build()
.filter_map(|entry| {
let entry = entry.ok()?;
let path = entry.path();
if !path.is_file() || path.extension().is_none_or(|ext| ext != "md") {
return None;
}
let relative_path = path.strip_prefix(base_path).ok()?;
let key = if let Some(parent) = relative_path.parent() {
if parent == std::path::Path::new("") {
to_file_name(path)
} else {
format!("{}/{}", parent.to_string_lossy(), to_file_name(path))
}
} else {
to_file_name(path)
};
fs::read_to_string(path).ok().map(|content| (key, content))
})
.collect()
}
pub fn new_from_hashmap(map: HashMap<String, String>) -> State {
map.into_iter().collect()
}
pub fn write_store_at_path(store: &State, to: &Path) -> std::io::Result<()> {
for (key, content) in store.iter() {
write_file(key, content, to)?;
}
Ok(())
}
fn to_file_name(path: &Path) -> String {
path.file_name()
.map(|name| name.to_string_lossy().trim_end_matches(".md").to_string())
.unwrap_or_default()
}