A static site generator written in Rust
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.

write.rs 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. use config::Config;
  2. use page::Page;
  3. use post::Post;
  4. use render::{render_page, render_post, render_post_listing};
  5. use std::fs;
  6. use std::path;
  7. pub fn write_post(
  8. cwd: &path::PathBuf,
  9. layout: &str,
  10. post_template: &str,
  11. post: &Post,
  12. config: &Config,
  13. ) {
  14. match fs::create_dir(cwd.join("public").join("posts").join(&post.slug)) {
  15. Ok(_) => {}
  16. Err(err) => match err.kind() {
  17. std::io::ErrorKind::AlreadyExists => {}
  18. _ => panic!(err),
  19. },
  20. }
  21. fs::write(
  22. cwd.join("public")
  23. .join("posts")
  24. .join(&post.slug)
  25. .join("index.html"),
  26. render_post(layout, post_template, post, config),
  27. )
  28. .expect("Unable to write file");
  29. }
  30. pub fn write_page(
  31. cwd: &path::PathBuf,
  32. layout: &str,
  33. page_template: &str,
  34. page: &Page,
  35. config: &Config,
  36. ) {
  37. match fs::create_dir(cwd.join("public").join(&page.slug)) {
  38. Ok(_) => {}
  39. Err(err) => match err.kind() {
  40. std::io::ErrorKind::AlreadyExists => {}
  41. _ => panic!(err),
  42. },
  43. }
  44. fs::write(
  45. cwd.join("public").join(&page.slug).join("index.html"),
  46. render_page(layout, page_template, page, config),
  47. )
  48. .expect("Unable to write file");
  49. }
  50. pub fn write_post_listing(
  51. cwd: &path::PathBuf,
  52. layout: &str,
  53. post_listing_template: &str,
  54. post_item_template: &str,
  55. posts: &Vec<Post>,
  56. config: &Config,
  57. ) {
  58. fs::write(
  59. cwd.join("public").join("index.html"),
  60. render_post_listing(
  61. layout,
  62. post_listing_template,
  63. post_item_template,
  64. posts,
  65. config,
  66. ),
  67. )
  68. .expect("Unable to write file");
  69. }
  70. #[cfg(test)]
  71. mod tests {
  72. use chrono::NaiveDate;
  73. #[allow(unused_imports)]
  74. use super::*;
  75. #[allow(unused_imports)]
  76. use std::{env, fs};
  77. #[allow(unused_imports)]
  78. use uuid::Uuid;
  79. #[test]
  80. fn test_write_post() {
  81. let temp_dir = env::temp_dir();
  82. let working_dir = temp_dir.join(&Uuid::new_v4().to_string());
  83. fs::create_dir(&working_dir).unwrap();
  84. env::set_current_dir(&working_dir).unwrap();
  85. let cwd = env::current_dir().unwrap();
  86. fs::create_dir(cwd.join("public")).unwrap();
  87. fs::create_dir(cwd.join("public").join("posts")).unwrap();
  88. let layout =
  89. "<html><head><title>{{ page_title }}</title></head><body>{{ contents }}</body></html>";
  90. let post_template = "<article><h1>{{ title }}</h1><div>{{ body }}</div></article>";
  91. let post = Post {
  92. title: String::from("Hello world"),
  93. body: String::from("Lorem ipsum dolor sit amet"),
  94. slug: String::from("hello-world"),
  95. date: NaiveDate::from_ymd(2019, 1, 1),
  96. };
  97. let config = Config {
  98. site_name: "Test Site".to_string(),
  99. };
  100. write_post(&cwd, &layout, &post_template, &post, &config);
  101. let content = fs::read_to_string(
  102. cwd.join("public")
  103. .join("posts")
  104. .join("hello-world")
  105. .join("index.html"),
  106. )
  107. .unwrap();
  108. assert_eq!(
  109. "<html><head><title>Hello world | Test Site</title></head><body><article><h1>Hello world</h1><div><p>Lorem ipsum dolor sit amet</p></div></article></body></html>",
  110. content.replace("\n", "")
  111. );
  112. fs::remove_dir_all(temp_dir.join(&working_dir)).unwrap();
  113. }
  114. #[test]
  115. fn test_write_post_listing() {
  116. let temp_dir = env::temp_dir();
  117. let working_dir = temp_dir.join(&Uuid::new_v4().to_string());
  118. fs::create_dir(&working_dir).unwrap();
  119. env::set_current_dir(&working_dir).unwrap();
  120. let cwd = env::current_dir().unwrap();
  121. fs::create_dir(cwd.join("public")).unwrap();
  122. let layout =
  123. "<html><head><title>{{ page_title }}</title></head><body>{{ contents }}</body></html>";
  124. let post_listing_template = "<ul>{{ post_listing }}</ul>";
  125. let post_item_template = "<li><a href=\"/{{ slug }}\">{{ title }}</a></li>";
  126. let posts = vec![
  127. Post {
  128. title: String::from("First post"),
  129. body: String::from("lorem ipsum dolor sit amet"),
  130. slug: String::from("first-post"),
  131. date: NaiveDate::from_ymd(2019, 1, 1),
  132. },
  133. Post {
  134. title: String::from("Second post"),
  135. body: String::from("lorem ipsum dolor sit amet"),
  136. slug: String::from("second-post"),
  137. date: NaiveDate::from_ymd(2019, 1, 1),
  138. },
  139. Post {
  140. title: String::from("Third post"),
  141. body: String::from("lorem ipsum dolor sit amet"),
  142. slug: String::from("third-post"),
  143. date: NaiveDate::from_ymd(2019, 1, 1),
  144. },
  145. ];
  146. let config = Config {
  147. site_name: "Test Site".to_string(),
  148. };
  149. write_post_listing(
  150. &cwd,
  151. &layout,
  152. &post_listing_template,
  153. &post_item_template,
  154. &posts,
  155. &config,
  156. );
  157. assert_eq!(
  158. "<html><head><title>Test Site</title></head><body><ul><li><a href=\"/first-post\">First post</a></li><li><a href=\"/second-post\">Second post</a></li><li><a href=\"/third-post\">Third post</a></li></ul></body></html>",
  159. fs::read_to_string(&cwd.join("public").join("index.html"))
  160. .unwrap()
  161. .replace("\n", ""),
  162. );
  163. fs::remove_dir_all(temp_dir.join(&working_dir)).unwrap();
  164. }
  165. }