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 WeaverConfig {
27    pub version: String,
28    pub base_dir: String,
29    pub content_dir: String,
30    pub base_url: String,
31    pub includes_dir: String,
32    pub public_dir: String,
33    pub template_dir: String,
34    pub build_dir: String,
35    pub templating_language: TemplateLang,
36    pub image_config: ImageConfig,
37}
38
39impl Default for WeaverConfig {
40    fn default() -> Self {
41        let base_path = std::env::var_os("WEAVING_BASE_PATH")
42            .unwrap_or(std::env::current_dir().unwrap().as_os_str().to_os_string())
43            .to_str()
44            .unwrap()
45            .to_string();
46
47        Self {
48            version: "1".into(),
49            base_dir: base_path.clone(),
50            content_dir: "content".into(),
51            base_url: "localhost:8080".into(),
52            includes_dir: "includes".into(),
53            public_dir: "public".into(),
54            build_dir: "site".into(),
55            template_dir: "templates".into(),
56            templating_language: TemplateLang::Liquid,
57            image_config: Default::default(),
58        }
59    }
60}
61
62impl WeaverConfig {
63    pub fn new() -> Self {
64        let inst = Self::default();
65
66        let config_file_result = std::fs::read_to_string(format!("{}/weaving.toml", inst.base_dir));
67
68        if config_file_result.is_err() {
69            return Self {
70                version: "1".into(),
71                base_dir: inst.base_dir.clone(),
72                content_dir: format!("{}/{}", &inst.base_dir, inst.content_dir),
73                template_dir: format!("{}/{}", &inst.base_dir, inst.template_dir),
74                base_url: inst.base_url,
75                includes_dir: format!("{}/{}", &inst.base_dir, inst.includes_dir),
76                public_dir: format!("{}/{}", &inst.base_dir, inst.public_dir),
77                build_dir: format!("{}/{}", &inst.base_dir, inst.build_dir),
78                templating_language: TemplateLang::Liquid,
79                image_config: inst.image_config,
80            };
81        }
82        let user_supplied_config: WeaverConfig =
83            toml::from_str(config_file_result.unwrap().as_str()).unwrap();
84
85        Self {
86            version: user_supplied_config.version,
87            base_dir: user_supplied_config.base_dir.clone(),
88            content_dir: format!(
89                "{}/{}",
90                &user_supplied_config.base_dir, user_supplied_config.content_dir
91            ),
92            base_url: user_supplied_config.base_url,
93            includes_dir: format!(
94                "{}/{}",
95                &user_supplied_config.base_dir, user_supplied_config.includes_dir
96            ),
97            public_dir: format!(
98                "{}/{}",
99                &user_supplied_config.base_dir, user_supplied_config.public_dir
100            ),
101            build_dir: format!(
102                "{}/{}",
103                &user_supplied_config.base_dir, user_supplied_config.build_dir
104            ),
105            template_dir: format!(
106                "{}/{}",
107                &user_supplied_config.base_dir, user_supplied_config.template_dir
108            ),
109            templating_language: user_supplied_config.templating_language,
110            image_config: user_supplied_config.image_config,
111        }
112    }
113
114    pub fn new_from_path(base_path: PathBuf) -> Self {
115        // Remove any trailing slash.
116        let safe_path = base_path.to_str().unwrap();
117        let config_file_result = std::fs::read_to_string(format!("{}/weaving.toml", safe_path));
118
119        if config_file_result.is_err() {
120            return Self::new();
121        }
122
123        let user_supplied_config: WeaverConfig =
124            toml::from_str(config_file_result.unwrap().as_str()).unwrap();
125
126        Self {
127            version: user_supplied_config.version,
128            base_dir: safe_path.to_string(),
129            content_dir: format!("{}/{}", &safe_path, user_supplied_config.content_dir),
130            base_url: user_supplied_config.base_url,
131            includes_dir: format!("{}/{}", &safe_path, user_supplied_config.includes_dir),
132            public_dir: format!("{}/{}", &safe_path, user_supplied_config.public_dir),
133            build_dir: format!("{}/{}", &safe_path, user_supplied_config.build_dir),
134            template_dir: format!("{}/{}", &safe_path, user_supplied_config.template_dir),
135            templating_language: user_supplied_config.templating_language,
136            image_config: user_supplied_config.image_config,
137        }
138    }
139}
140
141#[cfg(test)]
142mod test {
143    use super::*;
144    use pretty_assertions::assert_eq;
145
146    #[test]
147    fn test_defaultyness() {
148        let base_path = std::env::current_dir()
149            .unwrap()
150            .as_os_str()
151            .to_os_string()
152            .to_str()
153            .unwrap()
154            .to_string();
155        let config = WeaverConfig::new();
156
157        assert_eq!(config.base_dir, base_path);
158        assert_eq!(config.content_dir, format!("{}/content", base_path));
159        assert_eq!(config.includes_dir, format!("{}/includes", base_path));
160        assert_eq!(config.public_dir, format!("{}/public", base_path));
161        assert_eq!(config.build_dir, format!("{}/site", base_path));
162        assert_eq!(config.base_url, "localhost:8080");
163    }
164
165    #[test]
166    fn test_with_empty_config_file() {
167        let base_path_wd = std::env::current_dir()
168            .unwrap()
169            .as_os_str()
170            .to_os_string()
171            .to_str()
172            .unwrap()
173            .to_string();
174        let base_path = format!("{}/test_fixtures/config/empty_config", base_path_wd);
175        let config = WeaverConfig::new_from_path(base_path.clone().into());
176
177        assert_eq!(config.base_dir, base_path);
178        assert_eq!(config.content_dir, format!("{}/content", base_path));
179        assert_eq!(config.includes_dir, format!("{}/includes", base_path));
180        assert_eq!(config.public_dir, format!("{}/public", base_path));
181        assert_eq!(config.build_dir, format!("{}/site", base_path));
182        assert_eq!(config.base_url, "localhost:8080");
183    }
184
185    #[test]
186    fn test_with_filled_config_file() {
187        let base_path_wd = std::env::current_dir().unwrap().display().to_string();
188        let base_path = format!("{}/test_fixtures/config/custom_config", base_path_wd);
189        let config = WeaverConfig::new_from_path(base_path.clone().into());
190
191        assert_eq!(config.base_dir, base_path);
192        assert_eq!(config.content_dir, format!("{}/content", base_path));
193        assert_eq!(config.includes_dir, format!("{}/partials", base_path));
194        assert_eq!(config.public_dir, format!("{}/static", base_path));
195        assert_eq!(config.build_dir, format!("{}/site", base_path));
196        assert_eq!(config.base_url, "localhost:9090");
197    }
198
199    #[test]
200    fn test_with_partial_config_file() {
201        let base_path_wd = std::env::current_dir().unwrap().display().to_string();
202        let base_path = format!("{}/test_fixtures/config/partial_config", base_path_wd);
203        let config = WeaverConfig::new_from_path(base_path.clone().into());
204
205        assert_eq!(config.base_dir, base_path);
206        assert_eq!(config.content_dir, format!("{}/content", base_path));
207        assert_eq!(config.includes_dir, format!("{}/partials", base_path));
208        assert_eq!(config.public_dir, format!("{}/static", base_path));
209        assert_eq!(config.build_dir, format!("{}/site", base_path));
210        assert_eq!(config.base_url, "localhost:8080");
211    }
212}