60 lines
1.8 KiB
Rust
60 lines
1.8 KiB
Rust
use serde::{Deserialize, Serialize};
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
pub struct PostMetadata {
|
|
pub slug: String,
|
|
pub image_path: String,
|
|
pub title: String,
|
|
pub date: String,
|
|
pub description: String,
|
|
pub project_link: String,
|
|
pub draft: bool,
|
|
pub tags: Vec<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
pub struct Post {
|
|
pub metadata: PostMetadata,
|
|
pub content: String,
|
|
}
|
|
|
|
cfg_if::cfg_if! {
|
|
if #[cfg(feature = "ssr")] {
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum PostDeserializationError {
|
|
#[error("Invalid front matter")]
|
|
InvalidFrontMatter,
|
|
#[error("Invalid markdown")]
|
|
InvalidMarkdown,
|
|
}
|
|
|
|
impl TryFrom<String> for Post {
|
|
type Error = PostDeserializationError;
|
|
|
|
fn try_from(content: String) -> Result<Self, Self::Error> {
|
|
use gray_matter::{Matter, engine::YAML};
|
|
let matter = Matter::<YAML>::new();
|
|
let post_data = matter
|
|
.parse_with_struct::<PostMetadata>(&content)
|
|
.ok_or_else(|| PostDeserializationError::InvalidFrontMatter)?;
|
|
|
|
let content = post_data.content;
|
|
|
|
use pulldown_cmark::{Parser, Options, html};
|
|
let parser = Parser::new_ext(&content, Options::all());
|
|
let mut html_output = String::new();
|
|
html::push_html(&mut html_output, parser);
|
|
|
|
if html_output.is_empty() {
|
|
return Err(PostDeserializationError::InvalidMarkdown);
|
|
}
|
|
|
|
Ok(Self {
|
|
metadata: post_data.data,
|
|
content: html_output,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|