mdbook_journal/mdbook/
dto.rs

1use super::prelude::*;
2use crate::prelude::*;
3
4#[derive(Debug, Serialize, Deserialize, Default)]
5#[serde(transparent)]
6pub struct TopicMapDto {
7    pub data: BTreeMap<String, TopicDto>,
8}
9
10#[derive(Debug, Serialize, Deserialize, Default)]
11pub struct TopicDto {
12    pub virtual_root: Option<PathBuf>,
13    pub source_root: Option<PathBuf>,
14    pub path_mapping: Option<String>,
15    pub template: Option<String>,
16    pub leaf_template: Option<String>,
17    pub variables: VariableMapDto,
18}
19
20#[derive(Debug, Serialize, Deserialize, Default)]
21#[serde(transparent)]
22pub struct VariableMapDto {
23    pub data: BTreeMap<String, VariableDto>,
24}
25
26#[derive(Debug, Serialize, Deserialize, Default)]
27#[serde(default)]
28pub struct VariableDto {
29    pub required: bool,
30    pub default: Option<String>,
31}
32
33impl TryFrom<&Config> for TopicMapDto {
34    type Error = anyhow::Error;
35
36    fn try_from(config: &Config) -> Result<Self> {
37        if let Some(value) = config.get::<::toml::Value>("preprocessor.journal.topics")? {
38            Ok(Self::deserialize(value.clone())?)
39        } else {
40            Ok(Default::default())
41        }
42    }
43}
44
45impl TryFrom<TopicMapDto> for TopicMap {
46    type Error = anyhow::Error;
47
48    fn try_from(value: TopicMapDto) -> Result<Self> {
49        value
50            .data
51            .into_iter()
52            .try_fold(Self::default(), |map, key_val| {
53                map.insert(Topic::try_from(key_val)?)
54            })
55            .context("folding for TopicMap")
56    }
57}
58
59impl TryFrom<(String, TopicDto)> for Topic {
60    type Error = anyhow::Error;
61
62    fn try_from((name, topic): (String, TopicDto)) -> Result<Self> {
63        let mut builder = Topic::builder(name);
64
65        if let Some(path) = topic.source_root {
66            builder = builder.with_source_root(path);
67        }
68
69        if let Some(path) = topic.virtual_root {
70            builder = builder.with_virtual_root(path);
71        }
72
73        if let Some(mapping) = topic.path_mapping {
74            builder = builder
75                .with_path_mapping(mapping.as_str())
76                .with_context(|| format!("mapping with {}", mapping.as_str()))?;
77        }
78
79        if let Some(template) = topic.template {
80            builder = builder
81                .with_template(template.as_str())
82                .with_context(|| format!("template with: \n\n{}", template.as_str()))?;
83        }
84
85        if let Some(dir_template) = topic.leaf_template {
86            builder = builder
87                .with_leaf_template(dir_template.as_str())
88                .with_context(|| format!("directory template: \n\n{}", dir_template.as_str()))?;
89        }
90
91        for key_val in topic.variables.data.into_iter() {
92            builder = builder.add_variable(Variable::from(key_val));
93        }
94
95        Ok(builder.build())
96    }
97}
98
99impl From<(String, VariableDto)> for Variable {
100    fn from((name, data): (String, VariableDto)) -> Self {
101        let mut var = Variable::new(name);
102
103        if data.required {
104            var = var.required();
105        }
106
107        if let Some(value) = data.default {
108            var = var.default(value);
109        }
110
111        var
112    }
113}