1use std::fs;
2
3use chrono::NaiveDate;
4use markdown::{to_html_with_options, Options};
5use serde::{Deserialize, Serialize};
6
7use crate::{
8 common::{get_json_data, preview::get_preview, toc, BlogError, BlogJson},
9 types::Blog,
10};
11
12#[derive(Debug, Serialize, Deserialize, Clone)]
14pub struct LowBlogEntry {
15 pub title: String,
17 pub date: NaiveDate,
19 pub desc: Option<String>,
21 pub html: String,
23 pub slug: String,
25 pub tags: Vec<String>,
27 pub toc: Option<String>,
29 pub keywords: Option<Vec<String>>,
31 pub canonical_link: Option<String>,
33 pub author_name: Option<String>,
35 pub author_webpage: Option<String>,
37 last_modified: Option<NaiveDate>,
38 priority: Option<f64>,
39 previw_chars: Option<usize>,
40}
41
42impl Blog for LowBlogEntry {
43 fn create<T: AsRef<std::path::Path>>(
44 blog: T,
45 toc_generation_func: Option<&dyn Fn(&markdown::mdast::Node) -> String>,
46 preview_chars: Option<usize>,
47 ) -> Result<Self, crate::common::BlogError> {
48 let json = get_json_data(&blog)?;
49
50 let markdown = match fs::read_to_string(blog) {
51 Ok(x) => x,
52 Err(y) => return Err(BlogError::File(y)),
53 };
54
55 let html = match to_html_with_options(
56 &markdown,
57 &Options {
58 compile: markdown::CompileOptions {
59 allow_dangerous_html: true,
60 allow_dangerous_protocol: true,
61
62 ..markdown::CompileOptions::default()
63 },
64 ..markdown::Options::default()
65 },
66 ) {
67 Ok(x) => x,
68 Err(y) => return Err(BlogError::Markdown(y.to_string())),
69 };
70
71 let toc = toc(&markdown, toc_generation_func)?;
72
73 return Ok(LowBlogEntry {
74 title: json.title,
75 date: json.date,
76 desc: json.desc,
77 html: html,
78 slug: json.slug,
79 tags: json.tags,
80 toc: toc,
81 keywords: json.keywords,
82 canonical_link: json.canonical_link,
83 author_name: json.author_name,
84 author_webpage: json.author_webpage,
85 last_modified: json.last_modified,
86 priority: json.priority,
87 previw_chars: preview_chars,
88 });
89 }
90 fn get_title(&self) -> String {
91 return self.title.clone();
92 }
93
94 fn get_date_listed(&self) -> NaiveDate {
95 return self.date.clone();
96 }
97
98 fn get_description(&self) -> Option<String> {
99 return self.desc.clone();
100 }
101
102 fn get_html(&self) -> String {
103 return self.html.clone();
104 }
105
106 fn get_full_slug(&self) -> String {
107 return format!("{}/{}", self.get_date_listed(), self.get_part_slug());
108 }
109
110 fn get_part_slug(&self) -> String {
111 return self.slug.clone();
112 }
113
114 fn get_tags(&self) -> Vec<String> {
115 return self.tags.clone();
116 }
117
118 fn get_table_of_contents(&self) -> Option<String> {
119 return self.toc.clone();
120 }
121
122 fn get_keywords(&self) -> Option<Vec<String>> {
123 return self.keywords.clone();
124 }
125
126 fn get_canonicle_link(&self) -> Option<String> {
127 return self.canonical_link.clone();
128 }
129
130 fn get_author_name(&self) -> Option<String> {
131 return self.author_name.clone();
132 }
133
134 fn get_author_webpage(&self) -> Option<String> {
135 return self.author_webpage.clone();
136 }
137
138 fn get_preview(&self) -> String {
139 let preview = get_preview(&self.html, self.previw_chars);
140
141 return preview;
142 }
143
144 fn get_last_modified(&self) -> Option<NaiveDate> {
145 return self.last_modified.clone();
146 }
147
148 fn get_priority(&self) -> Option<f64> {
149 return self.priority.clone();
150 }
151}
152
153impl LowBlogEntry {
154 pub(crate) fn new(json: BlogJson, html: String, toc: Option<String>) -> Self {
155 return LowBlogEntry {
156 title: json.title,
157 date: json.date,
158 desc: json.desc,
159 html: html,
160 slug: json.slug,
161 tags: json.tags,
162 toc: toc,
163 keywords: json.keywords,
164 canonical_link: json.canonical_link,
165 author_name: json.author_name,
166 author_webpage: json.author_webpage,
167 last_modified: json.last_modified,
168 priority: json.priority,
169 previw_chars: None,
170 };
171 }
172}
173
174#[derive(Debug, Serialize, Deserialize, Clone)]
176pub struct PreviewBlogEntry {
177 pub title: String,
179 pub date: NaiveDate,
181 pub desc: Option<String>,
183 pub slug: String,
185 pub tags: Vec<String>,
187 pub keywords: Option<Vec<String>>,
189 pub canonical_link: Option<String>,
191 pub author_name: Option<String>,
193 pub author_webpage: Option<String>,
195 pub preview: String,
197}
198
199impl PreviewBlogEntry {
200 pub(crate) fn new(json: BlogJson, preview: String) -> Self {
201 return PreviewBlogEntry {
202 title: json.title,
203 date: json.date,
204 desc: json.desc,
205 slug: json.slug,
206 tags: json.tags,
207 keywords: json.keywords,
208 canonical_link: json.canonical_link,
209 author_name: json.author_name,
210 author_webpage: json.author_webpage,
211 preview: preview,
212 };
213 }
214}