1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//! Defines the [`Post`] type.
use crate::tag::Tag;
use gtmpl::Value;
use std::collections::HashSet;
use std::path::PathBuf;
use url::Url;
/// Represents a blog post.
#[derive(Clone)]
pub struct Post {
/// The output path where the final post file will be rendered.
pub file_path: PathBuf,
/// The address for the rendered post.
pub url: Url,
/// The title of the post.
pub title: String,
/// The date of the post.
pub date: String,
/// The body of the post.
pub body: String,
/// The tags associated with the post.
pub tags: HashSet<Tag>,
}
impl Post {
/// Converts a [`Post`] into a template-renderable [`Value`], representing
/// a full post (as opposed to [`Post::summarize`] which represents a
/// post summary). The resulting [`Value`] has fields:
///
/// * `url`: The url of the post
/// * `title`: The title of the post
/// * `date`: The published date of the post
/// * `body`: The post body
/// * `tags`: A list of tags associated with the post
pub fn to_value(&self) -> Value {
use std::collections::HashMap;
let mut m = HashMap::new();
m.insert("url".to_owned(), Value::String(self.url.to_string()));
m.insert("title".to_owned(), Value::String(self.title.clone()));
m.insert("date".to_owned(), Value::String(self.date.clone()));
m.insert("body".to_owned(), Value::String(self.body.clone()));
m.insert(
"tags".to_owned(),
Value::Array(self.tags.iter().map(Value::from).collect()),
);
Value::Object(m)
}
/// Returns the full post body unless a `<!-- more -->` tag was found, in
/// which case it returns the text up to that tag (the "summary" text). It
/// also returns a boolean value indicating whether or not the tag was
/// found.
pub fn summary(&self) -> (&str, bool) {
match self.body.find("<!-- more -->") {
None => (self.body.as_str(), false),
Some(idx) => (&self.body[..idx], true),
}
}
/// Converts a [`Post`] into a template-renderable [`Value`] representing a
/// post summary. The resulting [`Value`] has fields:
///
/// * `url`: The url of the post
/// * `title`: The title of the post
/// * `date`: The published date of the post
/// * `summary`: The post summary if there is a `<!-- more -->` tag or else
/// the full post body
/// * `summarized`: A boolean value representing whether or not a `<!--
/// more -->` tag was found and thus the post was truncated.
/// * `tags`: A list of tags associated with the post
pub fn summarize(&self) -> Value {
use std::collections::HashMap;
let (summary, summarized) = self.summary();
let mut m = HashMap::new();
m.insert("url".to_owned(), Value::String(self.url.to_string()));
m.insert("title".to_owned(), Value::String(self.title.clone()));
m.insert("date".to_owned(), Value::String(self.date.clone()));
m.insert("summary".to_owned(), Value::String(summary.to_string()));
m.insert("summarized".to_owned(), Value::Bool(summarized));
m.insert(
"tags".to_owned(),
Value::Array(self.tags.iter().map(Value::from).collect()),
);
Value::Object(m)
}
}