You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fs.rs 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. use async_std::fs::read_to_string;
  2. use std::env;
  3. use std::ffi::OsStr;
  4. use std::fs::{read_dir, File};
  5. use std::io::{Error, ErrorKind, Write};
  6. use std::path::PathBuf;
  7. use crate::post::Post;
  8. pub async fn get_all_posts() -> Result<Vec<Post>, Error> {
  9. let mut posts: Vec<Post> = vec![];
  10. for file in post_directory_contents()? {
  11. let file = file?;
  12. if let Some("json") = file.path().extension().and_then(OsStr::to_str) {
  13. let contents = read_post_from_disk(&file.path()).await?;
  14. let post = Post::from_str(&contents)?;
  15. posts.push(post);
  16. }
  17. }
  18. posts.sort_by_key(|el| el.date.clone());
  19. posts.reverse();
  20. Ok(posts)
  21. }
  22. pub async fn get_one_post(slug: String, show_drafts: bool) -> Result<Post, Error> {
  23. let posts_dir = get_posts_directory_path()?;
  24. let path = posts_dir.join(format!("{}.json", slug));
  25. let contents = read_post_from_disk(&path).await?;
  26. let post = Post::from_str(&contents)?;
  27. if post.draft && !show_drafts {
  28. Err(Error::new(
  29. ErrorKind::NotFound,
  30. format!("Can't find post with the slug '{}'", post.slug),
  31. ))
  32. } else {
  33. Ok(post)
  34. }
  35. }
  36. pub fn delete_post(slug: String) -> Result<(), Error> {
  37. let posts_dir = get_posts_directory_path()?;
  38. let path = posts_dir.join(format!("{}.json", slug));
  39. std::fs::remove_file(path)?;
  40. Ok(())
  41. }
  42. async fn read_post_from_disk(path: &PathBuf) -> Result<String, Error> {
  43. match read_to_string(&path).await {
  44. Ok(c) => Ok(c),
  45. Err(_) => Err(Error::new(
  46. ErrorKind::NotFound,
  47. format!(
  48. "Can't find post with the slug '{}'",
  49. path.file_stem().unwrap().to_str().unwrap()
  50. ),
  51. )),
  52. }
  53. }
  54. pub fn write_post_to_disk(post: &Post) -> Result<(), Error> {
  55. let mut path: PathBuf = get_posts_directory_path()?;
  56. let filename = format!("{}.json", post.slug);
  57. path = path.join(&filename);
  58. let mut file = File::create(&path)?;
  59. file.write_all(serde_json::to_string(&post)?.as_bytes())?;
  60. Ok(())
  61. }
  62. fn post_directory_contents() -> Result<std::fs::ReadDir, Error> {
  63. let path = get_posts_directory_path()?;
  64. match read_dir(path) {
  65. Ok(f) => Ok(f),
  66. Err(_) => Err(Error::new(
  67. ErrorKind::Other,
  68. "Posts directory does not exist",
  69. )),
  70. }
  71. }
  72. fn get_posts_directory_path() -> Result<PathBuf, Error> {
  73. match env::var("POSTS_DIR") {
  74. Ok(dir) => Ok(dir.into()),
  75. Err(_) => Err(Error::new(
  76. ErrorKind::Other,
  77. "Posts directory environment variable not set",
  78. )),
  79. }
  80. }