use async_std::fs::read_to_string; use std::env; use std::ffi::OsStr; use std::fs::{read_dir, File}; use std::io::{Error, ErrorKind, Write}; use std::path::PathBuf; use crate::post::Post; pub async fn get_all_posts() -> Result, Error> { let mut posts: Vec = vec![]; for file in post_directory_contents()? { let file = file?; if let Some("json") = file.path().extension().and_then(OsStr::to_str) { let contents = read_post_from_disk(&file.path()).await?; let post = Post::from_str(&contents)?; posts.push(post); } } posts.sort_by_key(|el| el.date.clone()); posts.reverse(); Ok(posts) } pub async fn get_one_post(post_id: String) -> Result { let posts_dir = get_posts_directory_path()?; let path = posts_dir.join(format!("{}.json", post_id)); let contents = read_post_from_disk(&path).await?; let post = Post::from_str(&contents)?; Ok(post) } pub fn delete_post(post_id: String) -> Result<(), Error> { let posts_dir = get_posts_directory_path()?; let path = posts_dir.join(format!("{}.json", post_id)); std::fs::remove_file(path)?; Ok(()) } async fn read_post_from_disk(path: &PathBuf) -> Result { match read_to_string(&path).await { Ok(c) => Ok(c), Err(_) => Err(Error::new( ErrorKind::NotFound, format!( "Can't find post with the id '{}'", path.file_stem().unwrap().to_str().unwrap() ), )), } } pub fn write_post_to_disk(post: &Post) -> Result<(), Error> { let mut path: PathBuf = get_posts_directory_path()?; let filename = format!("{}.json", post.id); path = path.join(&filename); let mut file = File::create(&path)?; file.write_all(serde_json::to_string(&post)?.as_bytes())?; Ok(()) } fn post_directory_contents() -> Result { let path = get_posts_directory_path()?; match read_dir(path) { Ok(f) => Ok(f), Err(_) => Err(Error::new( ErrorKind::Other, "Posts directory does not exist", )), } } fn get_posts_directory_path() -> Result { match env::var("POSTS_DIR") { Ok(dir) => Ok(dir.into()), Err(_) => Err(Error::new( ErrorKind::Other, "Posts directory environment variable not set", )), } }