catapulte_engine/
parser.rs

1use std::{collections::HashMap, path::PathBuf};
2
3pub use mrml::prelude::parser::Error;
4
5#[derive(Clone, Debug, Default, serde::Deserialize)]
6pub struct Config {
7    #[serde(default)]
8    pub include_loader: Vec<IncludeLoaderEntry>,
9}
10
11#[derive(Clone, Debug, Default, serde::Deserialize)]
12#[serde(tag = "type")]
13pub enum IncludeLoaderFilter {
14    StartsWith {
15        value: String,
16    },
17    #[default]
18    Any,
19}
20
21impl From<IncludeLoaderFilter> for mrml::prelude::parser::multi_loader::MultiIncludeLoaderFilter {
22    fn from(value: IncludeLoaderFilter) -> Self {
23        match value {
24            IncludeLoaderFilter::Any => {
25                mrml::prelude::parser::multi_loader::MultiIncludeLoaderFilter::Any
26            }
27            IncludeLoaderFilter::StartsWith { value } => {
28                mrml::prelude::parser::multi_loader::MultiIncludeLoaderFilter::StartsWith { value }
29            }
30        }
31    }
32}
33
34#[derive(Clone, Debug, serde::Deserialize)]
35pub struct IncludeLoaderEntry {
36    pub filter: IncludeLoaderFilter,
37    pub loader: IncludeLoaderConfig,
38}
39
40#[derive(Clone, Debug, serde::Deserialize)]
41#[serde(tag = "type")]
42pub enum IncludeLoaderConfig {
43    Local { root: String },
44    Memory { values: HashMap<String, String> },
45}
46
47impl IncludeLoaderConfig {
48    fn into_async_loader(
49        self,
50    ) -> Box<dyn mrml::prelude::parser::loader::AsyncIncludeLoader + Send + Sync> {
51        match self {
52            Self::Local { root } => Box::new(
53                mrml::prelude::parser::local_loader::LocalIncludeLoader::new(PathBuf::from(root)),
54            ),
55            Self::Memory { values } => {
56                Box::new(mrml::prelude::parser::memory_loader::MemoryIncludeLoader(
57                    mrml::prelude::hash::Map::from_iter(values),
58                ))
59            }
60        }
61    }
62}
63
64impl From<Config> for mrml::prelude::parser::AsyncParserOptions {
65    fn from(value: Config) -> Self {
66        Self {
67            include_loader: Box::new(
68                value
69                    .include_loader
70                    .into_iter()
71                    .fold(
72                        mrml::prelude::parser::multi_loader::MultiIncludeLoader::<
73                            Box<
74                                dyn mrml::prelude::parser::loader::AsyncIncludeLoader
75                                    + Send
76                                    + Sync
77                                    + 'static,
78                            >,
79                        >::new(),
80                        |loader, item| match item.filter {
81                            IncludeLoaderFilter::Any => {
82                                loader.with_any(item.loader.into_async_loader())
83                            }
84                            IncludeLoaderFilter::StartsWith { value } => {
85                                loader.with_starts_with(value, item.loader.into_async_loader())
86                            }
87                        },
88                    )
89                    .with_any(
90                        Box::<mrml::prelude::parser::noop_loader::NoopIncludeLoader>::default(),
91                    ),
92            ),
93        }
94    }
95}