weaver_lib/
config.rs

1use std::path::PathBuf;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
6#[serde(rename_all = "lowercase")]
7pub enum TemplateLang {
8    #[default]
9    Liquid,
10}
11
12#[derive(Serialize, Deserialize, PartialEq, 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, PartialEq, 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, PartialEq, 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    pub syntax_theme: String,
57}
58
59impl Default for WeaverConfig {
60    fn default() -> Self {
61        let base_path = std::env::var_os("WEAVING_BASE_PATH")
62            .unwrap_or(std::env::current_dir().unwrap().as_os_str().to_os_string())
63            .to_str()
64            .unwrap()
65            .to_string();
66
67        let base_url = std::env::var_os("WEAVING_BASE_URL")
68            .unwrap_or("http://localhost:8080".into())
69            .to_str()
70            .unwrap()
71            .to_string();
72
73        Self {
74            version: "1".into(),
75            base_dir: base_path.clone(),
76            content_dir: "content".into(),
77            base_url,
78            partials_dir: "partials".into(),
79            public_dir: "public".into(),
80            build_dir: "site".into(),
81            template_dir: "templates".into(),
82            templating_language: TemplateLang::Liquid,
83            image_config: Default::default(),
84            serve_config: Default::default(),
85            syntax_theme: "base16-ocean.dark".into(),
86        }
87    }
88}
89impl WeaverConfig {
90    pub fn new(base_dir: PathBuf) -> Self {
91        let base_dir_str = base_dir.display().to_string();
92
93        let config_file_result = std::fs::read_to_string(format!("{}/weaving.toml", base_dir_str));
94
95        let user_supplied_config: WeaverConfig = if let Ok(config_file) = config_file_result {
96            toml::from_str(config_file.as_str()).unwrap()
97        } else {
98            Self {
99                base_dir: base_dir_str.clone(),
100                ..Default::default()
101            }
102        };
103
104        Self {
105            base_dir: base_dir_str.clone(),
106            content_dir: format!("{}/{}", &base_dir_str, user_supplied_config.content_dir),
107            partials_dir: format!("{}/{}", &base_dir_str, user_supplied_config.partials_dir),
108            public_dir: format!("{}/{}", &base_dir_str, user_supplied_config.public_dir),
109            build_dir: format!("{}/{}", &base_dir_str, user_supplied_config.build_dir),
110            template_dir: format!("{}/{}", &base_dir_str, user_supplied_config.template_dir),
111            ..user_supplied_config
112        }
113    }
114}
115
116#[cfg(test)]
117mod test {
118    use super::*;
119    use pretty_assertions::assert_eq;
120
121    #[test]
122    fn test_defaultyness() {
123        let base_path = std::env::current_dir()
124            .unwrap()
125            .as_os_str()
126            .to_os_string()
127            .to_str()
128            .unwrap()
129            .to_string();
130        let config = WeaverConfig::new(base_path.clone().into());
131
132        assert_eq!(config.base_dir, base_path);
133        assert_eq!(config.content_dir, format!("{}/content", base_path));
134        assert_eq!(config.partials_dir, format!("{}/partials", base_path));
135        assert_eq!(config.public_dir, format!("{}/public", base_path));
136        assert_eq!(config.build_dir, format!("{}/site", base_path));
137        assert_eq!(config.base_url, "http://localhost:8080");
138    }
139
140    #[test]
141    fn test_with_empty_config_file() {
142        let base_path_wd = std::env::current_dir()
143            .unwrap()
144            .as_os_str()
145            .to_os_string()
146            .to_str()
147            .unwrap()
148            .to_string();
149        let base_path = format!("{}/test_fixtures/config/empty_config", base_path_wd);
150        let config = WeaverConfig::new(base_path.clone().into());
151
152        assert_eq!(config.base_dir, base_path);
153        assert_eq!(config.content_dir, format!("{}/content", base_path));
154        assert_eq!(config.partials_dir, format!("{}/partials", base_path));
155        assert_eq!(config.public_dir, format!("{}/public", base_path));
156        assert_eq!(config.build_dir, format!("{}/site", base_path));
157        assert_eq!(config.base_url, "http://localhost:8080");
158    }
159
160    #[test]
161    fn test_with_filled_config_file() {
162        let base_path_wd = std::env::current_dir().unwrap().display().to_string();
163        let base_path = format!("{}/test_fixtures/config/full_config", base_path_wd);
164        let config = WeaverConfig::new(base_path.clone().into());
165
166        assert_eq!(config.base_dir, base_path);
167        assert_eq!(config.content_dir, format!("{}/content", base_path));
168        assert_eq!(config.partials_dir, format!("{}/partials", base_path));
169        assert_eq!(config.public_dir, format!("{}/static", base_path));
170        assert_eq!(config.build_dir, format!("{}/site", base_path));
171        assert_eq!(config.base_url, "localhost:9090");
172        assert_eq!(config.image_config.quality, 100);
173        assert_eq!(config.serve_config.npm_build, true);
174        assert_eq!(config.serve_config.address, "localhost:3030");
175    }
176
177    #[test]
178    fn test_with_partial_config_file() {
179        let base_path_wd = std::env::current_dir().unwrap().display().to_string();
180        let base_path = format!("{}/test_fixtures/config/partial_config", base_path_wd);
181        let config = WeaverConfig::new(base_path.clone().into());
182
183        assert_eq!(config.base_dir, base_path);
184        assert_eq!(config.content_dir, format!("{}/content", base_path));
185        assert_eq!(config.partials_dir, format!("{}/partials", base_path));
186        assert_eq!(config.public_dir, format!("{}/static", base_path));
187        assert_eq!(config.build_dir, format!("{}/site", base_path));
188        assert_eq!(config.base_url, "http://localhost:8080");
189    }
190}