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
.*)\n\n(?P.*)").unwrap();
static ref slug_re: Regex = Regex::new(r"(?P\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 = 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 = 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 = 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();
}
}