Oregami
Repositories/oxedyne/fe2o3

oxedyne/fe2o3/fe2o3_steel/src/srv/dev/cfg.rs

6.7 KiB, 31 runs

created by r1870400018:977, which is this file's identity for as long as the history lasts, whatever it is later renamed to

download · who wrote it · its history

1use oxedyne_fe2o3_core::{
2 prelude::*,
3 file::PathState,
4 path::{
5 NormalPath,
6 NormPathBuf,
7 },
8};
9use oxedyne_fe2o3_jdat::{
10 prelude::*,
11 cfg::Config,
12};
13
14use std::{
15 collections::{
16 BTreeMap,
17 //HashMap,
18 },
19 path::{
20 Path,
21 PathBuf,
22 },
23};
24
25
26#[derive(Clone, Debug, Eq, PartialEq, FromDatMap, ToDatMap)]
27pub struct DevConfig {
28 pub src_path_rel: String,
29 pub js_bundles_rel: DaticleMap,
30 pub css_source_dir_rel: String,
31 pub css_bundle_rel: String,
32 pub js_import_aliases_rel: DaticleMap,
33}
34
35impl Config for DevConfig {}
36
37impl Default for DevConfig {
38 fn default() -> Self {
39 Self {
40 src_path_rel: fmt!("./www/src"),
41 js_bundles_rel: mapdat!{
42 "./www/src/js/pages/main/index.mjs" => "./www/public/bundles/js/main.bundle.js",
43 "./www/src/js/pages/admin/index.mjs" => "./www/public/bundles/js/admin.bundle.js",
44 }.get_map().unwrap_or(DaticleMap::new()),
45 css_source_dir_rel: fmt!("./www/src/styles"),
46 css_bundle_rel: fmt!("./www/public/styles.css"),
47 js_import_aliases_rel: mapdat!{
48 "@utils" => "./www/src/js/utils",
49 "@components" => "./www/src/js/components",
50 }.get_map().unwrap_or(DaticleMap::new()),
51 }
52 }
53}
54
55impl DevConfig {
56
57 pub fn validate(
58 &self,
59 root: &NormPathBuf,
60 )
61 -> Outcome<()>
62 {
63 // Only validate paths that exist - don't require all directories.
64 if !self.src_path_rel.is_empty() {
65 match PathState::DirMustExist.validate(root, &self.src_path_rel) {
66 Ok(()) => {
67 let _ = self.get_js_bundles_map(root).unwrap_or_else(|e| {
68 warn!("JS bundling configuration invalid: {}", e);
69 Vec::new()
70 });
71 let _ = self.get_css_paths(root).unwrap_or_else(|e| {
72 warn!("CSS bundling configuration invalid: {}", e);
73 (PathBuf::new(), PathBuf::new())
74 });
75 }
76 Err(_) => {
77 info!("Source directory '{}' not found, bundling disabled.",
78 self.src_path_rel);
79 }
80 }
81 }
82 Ok(())
83 }
84
85 pub fn has_js_bundling(&self, root: &NormPathBuf) -> bool {
86 self.get_js_bundles_map(root).is_ok() && !self.js_bundles_rel.is_empty()
87 }
88
89 pub fn has_css_bundling(&self, root: &NormPathBuf) -> bool {
90 self.get_css_paths(root).is_ok() && !self.css_source_dir_rel.is_empty()
91 }
92
93 pub fn get_js_bundles_map(
94 &self,
95 root: &NormPathBuf,
96 )
97 -> Outcome<Vec<(PathBuf, PathBuf)>>
98 {
99 let mut result = Vec::new();
100 for (entry_dat, bundle_dat) in &self.js_bundles_rel {
101
102 // Javascript/Typescript entry point file.
103 let entry_str = try_extract_dat!(entry_dat, Str);
104 let entry = Path::new(&entry_str).normalise();
105 if entry.escapes() {
106 return Err(err!(
107 "DevConfig: javascipt/typescript entry point {} escapes the directory {:?}.",
108 entry_str, root;
109 Invalid, Input, Path));
110 }
111 let entry = root.clone().join(entry).normalise().absolute();
112 res!(PathState::FileMustExist.validate(
113 root,
114 entry_str,
115 ));
116
117 // Target javascript bundle file.
118 let bundle_str = try_extract_dat!(bundle_dat, Str);
119 // Ensure that the file into which the javascript will be bundled stays within the root
120 // directory.
121 let bundle = Path::new(&bundle_str).normalise();
122 if bundle.escapes() {
123 return Err(err!(
124 "DevConfig: javascript bundle entry {} maps to a bundle path {} \
125 that escapes the directory {:?}.",
126 entry_str, bundle_str, root;
127 Invalid, Input, Path));
128 }
129 let bundle = root.clone().join(bundle).normalise().absolute();
130 result.push((entry.as_pathbuf(), bundle.as_pathbuf()));
131 }
132 Ok(result)
133 }
134
135 pub fn get_js_import_aliases(
136 &self,
137 root: &NormPathBuf,
138 )
139 -> Outcome<Vec<(String, PathBuf)>>
140 {
141 let mut result = Vec::new();
142 for (alias_dat, path_dat) in &self.js_import_aliases_rel {
143 let alias = try_extract_dat!(alias_dat, Str).clone();
144 let path_str = try_extract_dat!(path_dat, Str);
145 // Ensure that the file into which the javascript will be bundled stays within the root
146 // directory.
147 let path = Path::new(&path_str).normalise();
148 if path.escapes() {
149 return Err(err!(
150 "DevConfig: javascript import alias entry {} maps to a path {} \
151 that escapes the directory {:?}.",
152 alias, path_str, root;
153 Invalid, Input, Path));
154 }
155 let path = root.clone().join(path).normalise().absolute();
156 result.push((alias, path.as_pathbuf()));
157 }
158 Ok(result)
159 }
160
161 pub fn get_css_paths(
162 &self,
163 root: &NormPathBuf,
164 )
165 -> Outcome<(PathBuf, PathBuf)> // (source, target).
166 {
167 // Sass source directory.
168 let src_str = &self.css_source_dir_rel;
169 if src_str.is_empty() {
170 return Err(err!(
171 "DevConfig: Css source directory path is empty.";
172 Invalid, Input, Path));
173 }
174 let src = Path::new(&src_str).normalise();
175 if src.escapes() {
176 return Err(err!(
177 "DevConfig: Css source directory path {} escapes the directory {:?}.",
178 src_str, root;
179 Invalid, Input, Path));
180 }
181 let src = root.clone().join(src).normalise().absolute().as_pathbuf();
182 res!(PathState::DirMustExist.validate(
183 root,
184 &src_str,
185 ));
186
187 // Target css bundle file.
188 let trg_str = &self.css_bundle_rel;
189 if trg_str.is_empty() {
190 return Err(err!(
191 "DevConfig: Css target bundle file is empty.";
192 Invalid, Input, Path));
193 }
194 let trg = Path::new(&trg_str).normalise();
195 if trg.escapes() {
196 return Err(err!(
197 "DevConfig: Css target bundle file {} escapes the directory {:?}.",
198 trg_str, root;
199 Invalid, Input, Path));
200 }
201 let trg = root.clone().join(trg).normalise().absolute().as_pathbuf();
202
203 Ok((src, trg))
204 }
205}