use super::readable::ReadableDate;
use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
#[derive(Debug, Clone, PartialEq)]
pub enum Lang {
Apple,
Ringo,
Pinggo,
Apfel,
}
impl Default for Lang {
fn default() -> Self {
Self::Apple
}
}
impl Serialize for Lang {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(match *self {
Self::Apple => "Apple",
Self::Ringo => "林檎",
Self::Pinggo => "苹果",
Self::Apfel => "Apfel",
})
}
}
impl<'de> Deserialize<'de> for Lang {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
match String::deserialize(deserializer)?.as_ref() {
"Apple" | "Apples" | "apple" | "apples" => Ok(Self::Apple),
"林檎" | "リンゴ" | "りんご" | "Ringo" => Ok(Self::Ringo),
"苹果" | "蘋果" | "Pinggo" => Ok(Self::Pinggo),
"Apfel" | "Äpfel" => Ok(Self::Apfel),
s @ _ => Err(serde::de::Error::custom(format!(
"key [status] value not supported value {}",
s
))),
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum Status {
Draft,
Public,
Internal,
}
impl Default for Status {
fn default() -> Self {
Self::Draft
}
}
impl Serialize for Status {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(match *self {
Self::Draft => "Draft",
Self::Public => "Public",
Self::Internal => "Internal",
})
}
}
impl<'de> Deserialize<'de> for Status {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
match String::deserialize(deserializer)?.as_ref() {
"Draft" => Ok(Self::Draft),
"Public" => Ok(Self::Public),
"Internal" => Ok(Self::Internal),
s @ _ => Err(serde::de::Error::custom(format!(
"key [status] value not supported value {}",
s
))),
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct Banner {
#[serde(rename = "Outdate", default)]
pub outdate: i64,
}
fn default_template() -> String {
"Article".into()
}
fn default_stylesheet() -> String {
"latest".into()
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Render {
#[serde(rename = "Template", default = "default_template")]
pub template: String,
#[serde(rename = "Target", default)]
pub target: Option<std::path::PathBuf>,
#[serde(rename = "Stylesheet", default = "default_stylesheet")]
pub stylesheet: String,
}
impl Default for Render {
fn default() -> Self {
Self {
template: "Article".to_owned(),
target: None,
stylesheet: "latest".to_owned(),
}
}
}
#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
pub struct FrontMatter {
#[serde(rename = "Title")]
pub title: String,
#[serde(rename = "Create Date")]
pub create_date: ReadableDate,
#[serde(rename = "Last Update", default)]
pub last_update: Option<ReadableDate>,
#[serde(rename = "Language", default)]
pub lang: Lang,
#[serde(rename = "Description", default)]
pub description: Option<String>,
#[serde(rename = "Tags")]
pub tags: Option<Vec<String>>,
#[serde(rename = "Status", default)]
pub status: Status,
#[serde(rename = "Render", default)]
pub render: Render,
#[serde(rename = "Banner", default)]
pub banner: Banner,
}
#[cfg(test)]
mod test {
use super::*;
use serde_yaml;
#[test]
fn deserialize() {
let fm: FrontMatter = serde_yaml::from_str(
r"
Title: Foo
Create Date: Jan 12, 2001
Last Update: Feb 02, 2002
",
)
.unwrap();
assert_eq!(
fm,
FrontMatter {
title: "Foo".to_owned(),
create_date: ReadableDate::new(2001, 1, 12),
last_update: Some(ReadableDate::new(2002, 2, 02)),
status: Status::Draft,
..Default::default()
}
)
}
}