weaver_lib/
config.rs

1use std::path::PathBuf;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Serialize, Deserialize, Debug, Default)]
6#[serde(rename_all = "lowercase")]
7pub enum TemplateLang {
8    #[default]
9    Liquid,
10}
11
12#[derive(Serialize, Deserialize, Debug)]
13#[serde(default)]
14pub struct ImageConfig {
15    pub quality: u8,
16}
17
18impl Default for ImageConfig {
19    fn default() -> Self {
20        Self { quality: 83 }
21    }
22}
23
24#[derive(Serialize, Deserialize, Debug)]
25#[serde(default)]
26pub struct ServeConfig {
27    pub watch_excludes: Vec<String>,
28    pub address: String,
29    pub npm_build: bool,
30}
31
32impl Default for ServeConfig {
33    fn default() -> Self {
34        Self {
35            watch_excludes: vec![".git".into(), "node_modules".into(), "site".into()],
36            address: "localhost:8080".into(),
37            npm_build: false,
38        }
39    }
40}
41
42#[derive(Serialize, Deserialize, Debug)]
43#[serde(default)]
44pub struct WeaverConfig {
45    pub version: String,
46    pub base_dir: String,
47    pub content_dir: String,
48    pub base_url: String,
49    pub partials_dir: String,
50    pub public_dir: String,
51    pub template_dir: String,
52    pub build_dir: String,
53    pub templating_language: TemplateLang,
54    pub image_config: ImageConfig,
55    pub serve_config: ServeConfig,
56}
57
58impl Default for WeaverConfig {
59    fn default() -> Self {
60        let base_path = std::env::var_os("WEAVING_BASE_PATH")
61            .unwrap_or(std::env::current_dir().unwrap().as_os_str().to_os_string())
62            .to_str()
63            .unwrap()
64            .to_string();
65
66        Self {
67            version: "1".into(),
68            base_dir: base_path.clone(),
69            content_dir: "content".into(),
70            base_url: "localhost:8080".into(),
71            partials_dir: "partials".into(),
72            public_dir: "public".into(),
73            build_dir: "site".into(),
74            template_dir: "templates".into(),
75            templating_language: TemplateLang::Liquid,
76            image_config: Default::default(),
77            serve_config: Default::default(),
78        }
79    }
80}
81impl WeaverConfig {
82    pub fn new(base_dir: PathBuf) -> Self {
83        let base_dir_str = base_dir.display().to_string();
84
85        let config_file_result = std::fs::read_to_string(format!("{}/weaving.toml", base_dir_str));
86
87        let user_supplied_config: WeaverConfig = if let Ok(config_file) = config_file_result {
88            toml::from_str(config_file.as_str()).unwrap()
89        } else {
90            Self {
91                base_dir: base_dir_str.clone(),
92                ..Default::default()
93            }
94        };
95
96        Self {
97            version: user_supplied_config.version,
98            base_dir: base_dir_str.clone(),
99            content_dir: format!("{}/{}", &base_dir_str, user_supplied_config.content_dir),
100            base_url: user_supplied_config.base_url,
101            partials_dir: format!("{}/{}", &base_dir_str, user_supplied_config.partials_dir),
102            public_dir: format!("{}/{}", &base_dir_str, user_supplied_config.public_dir),
103            build_dir: format!("{}/{}", &base_dir_str, user_supplied_config.build_dir),
104            template_dir: format!("{}/{}", &base_dir_str, user_supplied_config.template_dir),
105            templating_language: user_supplied_config.templating_language,
106            image_config: user_supplied_config.image_config,
107            serve_config: user_supplied_config.serve_config,
108        }
109    }
110}
111
112#[cfg(test)]
113mod test {
114    use super::*;
115    use pretty_assertions::assert_eq;
116
117    #[test]
118    fn test_defaultyness() {
119        let base_path = std::env::current_dir()
120            .unwrap()
121            .as_os_str()
122            .to_os_string()
123            .to_str()
124            .unwrap()
125            .to_string();
126        let config = WeaverConfig::new(base_path.clone().into());
127
128        assert_eq!(config.base_dir, base_path);
129        assert_eq!(config.content_dir, format!("{}/content", base_path));
130        assert_eq!(config.partials_dir, format!("{}/partials", base_path));
131        assert_eq!(config.public_dir, format!("{}/public", base_path));
132        assert_eq!(config.build_dir, format!("{}/site", base_path));
133        assert_eq!(config.base_url, "localhost:8080");
134    }
135
136    #[test]
137    fn test_with_empty_config_file() {
138        let base_path_wd = std::env::current_dir()
139            .unwrap()
140            .as_os_str()
141            .to_os_string()
142            .to_str()
143            .unwrap()
144            .to_string();
145        let base_path = format!("{}/test_fixtures/config/empty_config", base_path_wd);
146        let config = WeaverConfig::new(base_path.clone().into());
147
148        assert_eq!(config.base_dir, base_path);
149        assert_eq!(config.content_dir, format!("{}/content", base_path));
150        assert_eq!(config.partials_dir, format!("{}/partials", base_path));
151        assert_eq!(config.public_dir, format!("{}/public", base_path));
152        assert_eq!(config.build_dir, format!("{}/site", base_path));
153        assert_eq!(config.base_url, "localhost:8080");
154    }
155
156    #[test]
157    fn test_with_filled_config_file() {
158        let base_path_wd = std::env::current_dir().unwrap().display().to_string();
159        let base_path = format!("{}/test_fixtures/config/full_config", base_path_wd);
160        let config = WeaverConfig::new(base_path.clone().into());
161
162        assert_eq!(config.base_dir, base_path);
163        assert_eq!(config.content_dir, format!("{}/content", base_path));
164        assert_eq!(config.partials_dir, format!("{}/partials", base_path));
165        assert_eq!(config.public_dir, format!("{}/static", base_path));
166        assert_eq!(config.build_dir, format!("{}/site", base_path));
167        assert_eq!(config.base_url, "localhost:9090");
168        assert_eq!(config.image_config.quality, 100);
169        assert_eq!(config.serve_config.npm_build, true);
170        assert_eq!(config.serve_config.address, "localhost:3030");
171    }
172
173    #[test]
174    fn test_with_partial_config_file() {
175        let base_path_wd = std::env::current_dir().unwrap().display().to_string();
176        let base_path = format!("{}/test_fixtures/config/partial_config", base_path_wd);
177        let config = WeaverConfig::new(base_path.clone().into());
178
179        assert_eq!(config.base_dir, base_path);
180        assert_eq!(config.content_dir, format!("{}/content", base_path));
181        assert_eq!(config.partials_dir, format!("{}/partials", base_path));
182        assert_eq!(config.public_dir, format!("{}/static", base_path));
183        assert_eq!(config.build_dir, format!("{}/site", base_path));
184        assert_eq!(config.base_url, "localhost:8080");
185    }
186}