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}