1use serde::de::DeserializeOwned;
3use serde::{Deserialize, Serialize};
4
5pub trait Page: Serialize + DeserializeOwned {
7 fn title(&self) -> String;
9}
10
11#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
13pub struct DefaultPage {
14 pub title: String,
15 #[serde(flatten, skip_serializing_if = "serde_yaml::Mapping::is_empty")]
17 pub extra: serde_yaml::Mapping,
18}
19
20impl Page for DefaultPage {
21 fn title(&self) -> String {
22 self.title.clone()
23 }
24}
25
26#[cfg(test)]
27mod test {
28 use super::*;
29 use serde_yaml::Value;
30
31 #[test]
33 fn default_page_de_serializes_missing_extra() {
34 let yaml: Value = serde_yaml::from_str("title: Title").unwrap();
35 let parsed: DefaultPage = serde_yaml::from_value(yaml.clone()).unwrap();
36 assert!(parsed.extra.is_empty());
37 let written = serde_yaml::to_value(&parsed).unwrap();
38 assert_eq!(written, yaml);
39 }
40
41 #[test]
43 fn default_page_de_serializes_extra() {
44 let yaml: Value = serde_yaml::from_str("title: Title\nmoar: stuff").unwrap();
45 let parsed: DefaultPage = serde_yaml::from_value(yaml.clone()).unwrap();
46 assert_eq!(&parsed.extra["moar"], "stuff");
47 let written = serde_yaml::to_value(&parsed).unwrap();
48 assert_eq!(written, yaml);
49 }
50}