Skip to content

Commit 66af6fb

Browse files
committed
extract Post struct in a separate file
1 parent 4fe5b42 commit 66af6fb

File tree

2 files changed

+112
-110
lines changed

2 files changed

+112
-110
lines changed

src/main.rs

Lines changed: 11 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,21 @@
1-
use std::{
2-
error::Error,
3-
fs::{self, File},
4-
io::Write,
5-
path::PathBuf,
6-
};
7-
8-
use comrak::ComrakOptions;
1+
mod posts;
92

3+
use crate::posts::Post;
104
use handlebars::{Context, Handlebars, Helper, HelperResult, Output, RenderContext, RenderError};
11-
12-
use serde_derive::{Deserialize, Serialize};
13-
use serde_json::json;
14-
155
use sass_rs::{compile_file, Options};
6+
use serde_derive::Serialize;
7+
use serde_json::json;
8+
use std::error::Error;
9+
use std::fs::{self, File};
10+
use std::io::Write;
11+
use std::path::PathBuf;
1612

1713
struct Blog {
1814
handlebars: Handlebars,
1915
posts: Vec<Post>,
2016
out_directory: PathBuf,
2117
}
2218

23-
#[derive(Debug, Serialize, Deserialize, Clone)]
24-
struct Post {
25-
filename: String,
26-
title: String,
27-
author: String,
28-
year: String,
29-
show_year: bool,
30-
month: String,
31-
day: String,
32-
contents: String,
33-
url: String,
34-
published: String,
35-
release: bool,
36-
}
37-
38-
#[derive(Debug, PartialEq, Serialize, Deserialize)]
39-
struct YamlHeader {
40-
title: String,
41-
author: String,
42-
#[serde(default)]
43-
release: bool,
44-
}
45-
4619
#[derive(Debug, Serialize)]
4720
struct Releases {
4821
releases: Vec<ReleasePost>,
@@ -115,91 +88,19 @@ impl Blog {
11588
let mut posts = Vec::new();
11689

11790
for entry in fs::read_dir(dir)? {
118-
let entry = entry?;
119-
let path = entry.path();
120-
121-
// yeah this might blow up, but it won't
122-
let filename = path.file_name().unwrap().to_str().unwrap();
91+
let path = entry?.path();
12392

12493
// ignore vim temporary files
94+
let filename = path.file_name().unwrap().to_str().unwrap();
12595
if filename.starts_with(".") && filename.ends_with(".swp") {
12696
continue;
12797
}
12898

129-
// we need to get the metadata out of the url
130-
let mut split = filename.splitn(4, "-");
131-
132-
let year = split.next().unwrap().to_string();
133-
let month = split.next().unwrap().to_string();
134-
let day = split.next().unwrap().to_string();
135-
let filename = split.next().unwrap().to_string();
136-
137-
let contents = fs::read_to_string(path)?;
138-
139-
// yaml headers.... we know the first four bytes of each file are "---\n"
140-
// so we need to find the end. we need the fours to adjust for those first bytes
141-
let end_of_yaml = contents[4..].find("---").unwrap() + 4;
142-
let yaml = &contents[..end_of_yaml];
143-
let YamlHeader {
144-
author,
145-
title,
146-
release,
147-
} = serde_yaml::from_str(yaml)?;
148-
// next, the contents. we add + to get rid of the final "---\n\n"
149-
let options = ComrakOptions {
150-
ext_header_ids: Some(String::new()),
151-
..ComrakOptions::default()
152-
};
153-
154-
let contents = comrak::markdown_to_html(&contents[end_of_yaml + 5..], &options);
155-
156-
// finally, the url.
157-
let mut url = PathBuf::from(&*filename);
158-
url.set_extension("html");
159-
160-
// this is fine
161-
let url = format!("{}/{}/{}/{}", year, month, day, url.to_str().unwrap());
162-
163-
// build the published time. this is only approximate, which is fine.
164-
// we do some unwraps because these need to be valid
165-
let published = time::Tm {
166-
tm_sec: 0,
167-
tm_min: 0,
168-
tm_hour: 0,
169-
tm_mday: day.parse::<i32>().unwrap(),
170-
tm_mon: month.parse::<i32>().unwrap() - 1, // 0-11 not 1-12
171-
tm_year: year.parse::<i32>().unwrap() - 1900, // from the year 1900, not the actual year
172-
// these next two fields are wrong but we never use them to generate our times
173-
tm_wday: 1,
174-
tm_yday: 1,
175-
tm_isdst: 0,
176-
tm_utcoff: 0,
177-
tm_nsec: 0,
178-
};
179-
180-
let published = published.rfc3339().to_string();
181-
182-
let post = Post {
183-
filename,
184-
title,
185-
author,
186-
year,
187-
show_year: false,
188-
month,
189-
day,
190-
contents,
191-
url,
192-
published,
193-
release,
194-
};
195-
196-
posts.push(post);
99+
posts.push(Post::open(&path)?);
197100
}
198101

199102
// finally, sort the posts. oldest first.
200-
201103
posts.sort_by_key(|post| post.url.clone());
202-
203104
posts.reverse();
204105

205106
for i in 1..posts.len() {

src/posts.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
use comrak::ComrakOptions;
2+
use serde_derive::{Deserialize, Serialize};
3+
use std::error::Error;
4+
use std::path::{Path, PathBuf};
5+
6+
#[derive(Debug, PartialEq, Deserialize)]
7+
struct YamlHeader {
8+
title: String,
9+
author: String,
10+
#[serde(default)]
11+
release: bool,
12+
}
13+
14+
#[derive(Debug, Clone, Serialize)]
15+
pub(crate) struct Post {
16+
pub(crate) filename: String,
17+
pub(crate) title: String,
18+
pub(crate) author: String,
19+
pub(crate) year: String,
20+
pub(crate) show_year: bool,
21+
pub(crate) month: String,
22+
pub(crate) day: String,
23+
pub(crate) contents: String,
24+
pub(crate) url: String,
25+
pub(crate) published: String,
26+
pub(crate) release: bool,
27+
}
28+
29+
impl Post {
30+
pub(crate) fn open(path: &Path) -> Result<Self, Box<dyn Error>> {
31+
// yeah this might blow up, but it won't
32+
let filename = path.file_name().unwrap().to_str().unwrap();
33+
34+
// we need to get the metadata out of the url
35+
let mut split = filename.splitn(4, "-");
36+
37+
let year = split.next().unwrap().to_string();
38+
let month = split.next().unwrap().to_string();
39+
let day = split.next().unwrap().to_string();
40+
let filename = split.next().unwrap().to_string();
41+
42+
let contents = std::fs::read_to_string(path)?;
43+
44+
// yaml headers.... we know the first four bytes of each file are "---\n"
45+
// so we need to find the end. we need the fours to adjust for those first bytes
46+
let end_of_yaml = contents[4..].find("---").unwrap() + 4;
47+
let yaml = &contents[..end_of_yaml];
48+
let YamlHeader {
49+
author,
50+
title,
51+
release,
52+
} = serde_yaml::from_str(yaml)?;
53+
// next, the contents. we add + to get rid of the final "---\n\n"
54+
let options = ComrakOptions {
55+
ext_header_ids: Some(String::new()),
56+
..ComrakOptions::default()
57+
};
58+
59+
let contents = comrak::markdown_to_html(&contents[end_of_yaml + 5..], &options);
60+
61+
// finally, the url.
62+
let mut url = PathBuf::from(&*filename);
63+
url.set_extension("html");
64+
65+
// this is fine
66+
let url = format!("{}/{}/{}/{}", year, month, day, url.to_str().unwrap());
67+
68+
// build the published time. this is only approximate, which is fine.
69+
// we do some unwraps because these need to be valid
70+
let published = time::Tm {
71+
tm_sec: 0,
72+
tm_min: 0,
73+
tm_hour: 0,
74+
tm_mday: day.parse::<i32>().unwrap(),
75+
tm_mon: month.parse::<i32>().unwrap() - 1, // 0-11 not 1-12
76+
tm_year: year.parse::<i32>().unwrap() - 1900, // from the year 1900, not the actual year
77+
// these next two fields are wrong but we never use them to generate our times
78+
tm_wday: 1,
79+
tm_yday: 1,
80+
tm_isdst: 0,
81+
tm_utcoff: 0,
82+
tm_nsec: 0,
83+
};
84+
85+
let published = published.rfc3339().to_string();
86+
87+
Ok(Self {
88+
filename,
89+
title,
90+
author,
91+
year,
92+
show_year: false,
93+
month,
94+
day,
95+
contents,
96+
url,
97+
published,
98+
release,
99+
})
100+
}
101+
}

0 commit comments

Comments
 (0)