123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- use std::fs;
- use std::path;
-
- use regex::Regex;
-
- #[derive(Debug)]
- pub struct Post {
- pub title: String,
- pub body: String,
- pub slug: String,
- }
-
- pub fn read_posts_dir(cwd: &path::PathBuf) -> fs::ReadDir {
- match fs::read_dir(cwd) {
- Ok(posts) => posts,
- Err(err) => panic!(err),
- }
- }
-
- pub fn parse_post(path: path::PathBuf) -> Post {
- let contents = fs::read_to_string(&path).expect("Couldn't read post file");
-
- lazy_static! {
- static ref re: Regex = Regex::new(r"^# (?P<title>.*)\n\n(?s)(?P<body>.*)").unwrap();
- static ref slug_re: Regex = Regex::new(r"(?P<slug>\S+).md").unwrap();
- }
-
- let title = &re.captures(&contents).expect("Couldn't parse title")["title"];
- let body = &re.captures(&contents).expect("Couldn't parse body")["body"];
-
- let filename = &path.file_name().unwrap().to_str().unwrap();
- let slug = &slug_re.captures(filename).expect("Couldn't parse slug")["slug"];
- Post {
- title: String::from(title),
- body: String::from(body),
- slug: String::from(slug),
- }
- }
-
- #[cfg(test)]
- mod tests {
- #[allow(unused_imports)]
- use super::*;
- #[allow(unused_imports)]
- #[allow(unused_imports)]
- use std::{env, fs, path};
- #[allow(unused_imports)]
- use uuid::Uuid;
-
- #[test]
- fn test_read_posts_dir() {
- let temp_dir = env::temp_dir();
- let working_dir = temp_dir.join(&Uuid::new_v4().to_string());
- fs::create_dir(&working_dir).unwrap();
- env::set_current_dir(&working_dir).unwrap();
-
- let cwd = env::current_dir().unwrap();
- fs::create_dir(cwd.join("posts")).unwrap();
-
- let post_body = "# This is a post\n\nHere is some content that goes in the post";
-
- let mut uuids: Vec<String> = vec![];
-
- for _ in 1..11 {
- let uuid = String::from(Uuid::new_v4().to_string());
- uuids.push(uuid.clone());
- fs::write(
- cwd.join("posts").join(format!("{}.md", &uuid)),
- &String::from(post_body),
- ).unwrap();
- }
-
- let mut expected_paths: Vec<String> = uuids
- .into_iter()
- .map(|uuid| {
- String::from(
- cwd.join("posts")
- .join(format!("{}.md", uuid))
- .to_str()
- .unwrap(),
- )
- }).collect();
- expected_paths.sort();
- let mut actual_paths: Vec<String> = read_posts_dir(&cwd.join("posts"))
- .into_iter()
- .map(|dir_entry| String::from(dir_entry.unwrap().path().to_str().unwrap()))
- .collect();
- actual_paths.sort();
-
- assert_eq!(expected_paths, actual_paths);
-
- fs::remove_dir_all(temp_dir.join(&working_dir)).unwrap();
- }
-
- #[test]
- fn test_parse_post() {
- let temp_dir = env::temp_dir();
- let working_dir = temp_dir.join(&Uuid::new_v4().to_string());
- fs::create_dir(&working_dir).unwrap();
- env::set_current_dir(&working_dir).unwrap();
-
- let cwd = env::current_dir().unwrap();
- fs::create_dir(cwd.join("posts")).unwrap();
-
- let slug = Uuid::new_v4().to_string();
- let filename = format!("{}.md", slug);
- fs::write(
- cwd.join("posts").join(&filename),
- "# This is a post\n\nHere is some content that goes in the post",
- ).unwrap();
-
- let post = parse_post(cwd.join("posts").join(&filename));
- assert_eq!("This is a post", post.title);
- assert_eq!("Here is some content that goes in the post", post.body);
- assert_eq!(slug, post.slug);
-
- fs::remove_dir_all(temp_dir.join(&working_dir)).unwrap();
- }
-
- #[test]
- fn test_post_with_multiple_paragraphs() {
- let temp_dir = env::temp_dir();
- let working_dir = temp_dir.join(&Uuid::new_v4().to_string());
- fs::create_dir(&working_dir).unwrap();
- env::set_current_dir(&working_dir).unwrap();
-
- let cwd = env::current_dir().unwrap();
- fs::create_dir(cwd.join("posts")).unwrap();
-
- let slug = Uuid::new_v4().to_string();
- let filename = format!("{}.md", slug);
- fs::write(
- cwd.join("posts").join(&filename),
- "# This is a post\n\nHere is a line\n\nHere is another line\n\nAnd a third",
- ).unwrap();
-
- let post = parse_post(cwd.join("posts").join(&filename));
- assert_eq!("This is a post", post.title);
- assert_eq!(
- "Here is a line\n\nHere is another line\n\nAnd a third",
- post.body
- );
- assert_eq!(slug, post.slug);
-
- fs::remove_dir_all(temp_dir.join(&working_dir)).unwrap();
- }
- }
|