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)
}
}