1
2
3
4
5#[ allow (unused_imports) ]
6use ::std::{
7
8 cell,
9 env,
10 ffi,
11 fmt,
12 fs,
13 io,
14 iter,
15 mem,
16 path,
17 rc,
18
19 collections::BTreeSet,
20 iter::Iterator,
21 path::{Path, PathBuf},
22
23 str::FromStr as _,
24 fmt::{Write as _},
25 io::{Write as _},
26
27 };
28
29
30use ::globset;
31use ::walkdir;
32use ::blake2;
33use ::proc_macro2;
34
35
36use crate::builder_errors::*;
37
38
39
40
41#[ derive (Clone, Debug) ]
42pub struct BuilderConfiguration {
43
44 pub sources : Option<PathBuf>,
45 #[ cfg (feature = "builder-assets") ]
46 pub assets_sources : Option<PathBuf>,
47 #[ cfg (feature = "builder-askama") ]
48 pub templates_sources : Option<PathBuf>,
49 #[ cfg (feature = "builder-markdown") ]
50 pub markdowns_sources : Option<PathBuf>,
51
52 #[ cfg (feature = "builder-assets") ]
53 pub assets_route_base : Option<PathBuf>,
54
55 #[ cfg (feature = "builder-assets") ]
56 pub css_route_base : Option<PathBuf>,
57 #[ cfg (feature = "builder-assets") ]
58 pub js_route_base : Option<PathBuf>,
59
60 #[ cfg (feature = "builder-assets") ]
61 pub images_route_base : Option<PathBuf>,
62 #[ cfg (feature = "builder-assets") ]
63 pub icons_route_base : Option<PathBuf>,
64 #[ cfg (feature = "builder-assets") ]
65 pub favicons_route_base : Option<PathBuf>,
66 #[ cfg (feature = "builder-assets") ]
67 pub fonts_route_base : Option<PathBuf>,
68
69 pub outputs : PathBuf,
70 pub generated : PathBuf,
71}
72
73
74impl Default for BuilderConfiguration {
75
76 fn default () -> Self {
77
78 let _sources = Self::resolve_sources () .or_panic (0xc6e7914d);
79 let _outputs = Self::resolve_outputs () .or_panic (0x344e2c9e);
80
81 #[ cfg (feature = "builder-assets") ]
82 let _assets_sources = _sources.join ("./assets");
83 #[ cfg (feature = "builder-assets") ]
84 let _assets_sources = if _assets_sources.exists () { Some (_assets_sources) } else { None };
85
86 #[ cfg (feature = "builder-askama") ]
87 let _templates_sources = _sources.join ("./templates");
88 #[ cfg (feature = "builder-askama") ]
89 let _templates_sources = if _templates_sources.exists () { Some (_templates_sources) } else { None };
90
91 #[ cfg (feature = "builder-markdown") ]
92 let _markdowns_sources = _sources.join ("./markdown");
93 #[ cfg (feature = "builder-markdown") ]
94 let _markdowns_sources = if _markdowns_sources.exists () { Some (_markdowns_sources) } else { None };
95
96 let _generated = _outputs.join ("./hss-builder-generated-default.in");
97
98 #[ cfg (feature = "builder-assets") ]
99 let _assets_route_base = Some (PathBuf::from ("/assets"));
100
101 #[ cfg (feature = "builder-assets") ]
102 let _css_route_base = Some (PathBuf::from ("/assets/css"));
103 #[ cfg (feature = "builder-assets") ]
104 let _js_route_base = Some (PathBuf::from ("/assets/js"));
105
106 #[ cfg (feature = "builder-assets") ]
107 let _images_route_base = Some (PathBuf::from ("/assets/images"));
108 #[ cfg (feature = "builder-assets") ]
109 let _icons_route_base = Some (PathBuf::from ("/assets/icons"));
110 #[ cfg (feature = "builder-assets") ]
111 let _favicons_route_base = Some (PathBuf::from ("/assets/favicons"));
112 #[ cfg (feature = "builder-assets") ]
113 let _fonts_route_base = Some (PathBuf::from ("/assets/fonts"));
114
115 Self {
116
117 sources : Some (_sources),
118 #[ cfg (feature = "builder-assets") ]
119 assets_sources : _assets_sources,
120 #[ cfg (feature = "builder-askama") ]
121 templates_sources : _templates_sources,
122 #[ cfg (feature = "builder-markdown") ]
123 markdowns_sources : _markdowns_sources,
124
125 #[ cfg (feature = "builder-assets") ]
126 assets_route_base : _assets_route_base,
127
128 #[ cfg (feature = "builder-assets") ]
129 css_route_base : _css_route_base,
130 #[ cfg (feature = "builder-assets") ]
131 js_route_base : _js_route_base,
132
133 #[ cfg (feature = "builder-assets") ]
134 images_route_base : _images_route_base,
135 #[ cfg (feature = "builder-assets") ]
136 icons_route_base : _icons_route_base,
137 #[ cfg (feature = "builder-assets") ]
138 favicons_route_base : _favicons_route_base,
139 #[ cfg (feature = "builder-assets") ]
140 fonts_route_base : _fonts_route_base,
141
142 outputs : _outputs,
143 generated : _generated,
144 }
145 }
146}
147
148
149impl BuilderConfiguration {
150
151 pub fn minimal () -> BuilderResult<Self> {
152
153 let _sources = Self::resolve_sources () ?;
154 let _outputs = Self::resolve_outputs () ?;
155 let _generated = _outputs.join ("./hss-builder-generated-default.in");
156
157 let _builder = Self {
158
159 sources : Some (_sources),
160
161 #[ cfg (feature = "builder-assets") ]
162 assets_sources : None,
163 #[ cfg (feature = "builder-askama") ]
164 templates_sources : None,
165 #[ cfg (feature = "builder-markdown") ]
166 markdowns_sources : None,
167
168 #[ cfg (feature = "builder-assets") ]
169 assets_route_base : None,
170
171 #[ cfg (feature = "builder-assets") ]
172 css_route_base : None,
173 #[ cfg (feature = "builder-assets") ]
174 js_route_base : None,
175
176 #[ cfg (feature = "builder-assets") ]
177 images_route_base : None,
178 #[ cfg (feature = "builder-assets") ]
179 icons_route_base : None,
180 #[ cfg (feature = "builder-assets") ]
181 favicons_route_base : None,
182 #[ cfg (feature = "builder-assets") ]
183 fonts_route_base : None,
184
185 outputs : _outputs,
186 generated : _generated,
187 };
188
189 Ok (_builder)
190 }
191
192 pub fn resolve_sources () -> BuilderResult<PathBuf> {
193 let _sources = PathBuf::from (env::var ("CARGO_MANIFEST_DIR") .or_wrap (0x4c6c04d8) ?);
194 if ! _sources.is_dir () {
195 return Err (error_with_code (0x148bc689));
196 }
197 normalize_path (&_sources)
198 }
199
200 pub fn resolve_outputs () -> BuilderResult<PathBuf> {
201 let _outputs = PathBuf::from (env::var ("OUT_DIR") .or_wrap (0xf039039f) ?);
202 if ! _outputs.is_dir () {
203 return Err (error_with_code (0xfcee6b4d));
204 }
205 normalize_path (&_outputs)
206 }
207}
208
209
210
211
212pub struct Builder {
213 configuration : BuilderConfiguration,
214 generated : String,
215 counter : u32,
216 route_names : Vec<String>,
217 dependencies : BTreeSet<PathBuf>,
218}
219
220
221impl Builder {
222
223 pub fn new (_configuration : BuilderConfiguration) -> Self {
224 Self {
225 configuration : _configuration,
226 generated : String::with_capacity (1024 * 1024),
227 counter : 1,
228 route_names : Vec::new (),
229 dependencies : BTreeSet::new (),
230 }
231 }
232
233 pub fn new_with_defaults () -> Self {
234 Self::new (BuilderConfiguration::default ())
235 }
236}
237
238
239
240
241impl Builder {
242
243
244
245
246 fn route_asset_raw (&mut self, _relative : &Path, _source : &Path, _content_type : &str, _route_base : Option<&Path>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized), _macro : &str, _source_0 : &str, _source_relative : Option<&Path>) -> BuilderResult {
247
248 let _route = _route_builder.build (_relative, &_source, _route_base, None) ?;
249 let _extensions = _extensions_builder.build () ?;
250
251 let _id = self.generate_id ();
252
253 let _description = if let Some (_relative) = _source_relative {
254 format! ("{} ({}, from = `{}`, file = `...{}`)", _macro, _content_type, _source_0, _relative.display ())
255 } else {
256 format! ("{} ({}, file = `{}`)", _macro, _content_type, _source_0)
257 };
258
259 self.route_names.push (format! ("Route_{}", _id));
260
261 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
262 self.dependencies_include (&_source) ?;
263
264 let _mode = "auto";
265
266 writeln! (self.generated, "::hyper_static_server::resource! (Resource_{}, {}, {}, (relative_to_cwd, {:?}), {:?});", _id, _content_type, _mode, _source, _description) .infallible (0x5fa962ac);
267 writeln! (self.generated, "::hyper_static_server::route! (Route_{}, Resource_{}, {:?}, {});", _id, _id, _route, _extensions) .infallible (0x46de4cc9);
268
269 Ok (())
270 }
271
272
273
274
275 #[ cfg (feature = "builder-askama") ]
276 pub fn route_askama (&mut self, _source_0 : &str, _context : Option<(&str, Option<&str>)>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
277
278 let _templates_sources = self.configuration.templates_sources.as_ref () .map (PathBuf::as_path);
279 let (_relative, _source) = self.resolve_file (_templates_sources, _source_0) ?;
280
281 let _route_base = Some (Path::new ("/"));
282
283 self.route_askama_0 (&_relative, &_source, _context, _route_base, _route_builder, _extensions_builder, _source_0, None)
284 }
285
286 #[ cfg (feature = "builder-askama") ]
287 pub fn route_askamas (&mut self, _sources_0 : &str, _glob : Option<&str>, _context : Option<(&str, Option<&str>)>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
288
289 let _templates_sources = self.configuration.templates_sources.as_ref () .map (PathBuf::as_path);
290 let (_files, _folders) = self.resolve_files (_templates_sources, _sources_0, _glob) ?;
291
292 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
293 self.dependencies_include_all (_folders.iter () .map (PathBuf::as_path)) ?;
294
295 let _route_base = Some (Path::new ("/"));
296
297 for (_relative, _source) in _files.into_iter () {
298
299 self.route_askama_0 (&_relative, &_source, _context, _route_base, _route_builder, _extensions_builder, _sources_0, Some (_relative.as_path ())) ?;
300 }
301
302 Ok (())
303 }
304
305
306 #[ cfg (feature = "builder-askama") ]
307 fn route_askama_0 (&mut self, _relative : &Path, _source : &Path, _context : Option<(&str, Option<&str>)>, _route_base : Option<&Path>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized), _source_0 : &str, _source_relative : Option<&Path>) -> BuilderResult {
308
309 let _relative_1 = _relative.with_extension ("");
310
311 let _template = _relative.strip_prefix ("/") .infallible (0x7285dc26);
312
313 let _route = _route_builder.build (&_relative_1, &_source, _route_base, None) ?;
314 let _extensions = _extensions_builder.build () ?;
315
316 let _id = self.generate_id ();
317
318 let _content_type = "html";
319 let _description = if let Some (_relative) = _source_relative {
320 format! ("askama ({}, from = `{}`, file = `...{}`)", _content_type, _source_0, _relative.display ())
321 } else {
322 format! ("askama ({}, file = `{}`)", _content_type, _source_0)
323 };
324
325 self.route_names.push (format! ("Route_{}", _id));
326
327 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
328 self.dependencies_include (&_source) ?;
329
330 let (_context_type, _context_path) = _context.unwrap_or (("()", None));
331 if let Some (_context_path) = _context_path {
332
333 let _sources = self.configuration.sources.as_ref () .map (PathBuf::as_path);
334 let (_, _context_path) = self.resolve_file (None, _context_path) ?;
335 let _context_encoding = match _context_path.extension () .or_wrap (0x70d90b37) ? .to_str () .or_wrap (0xa22f0541) ? {
336 "toml" => "toml",
337 "yaml" => "yaml",
338 "json" => "json",
339 _ =>
340 return Err (error_with_format (0xcbc42494, format_args! ("{}", _context_path.display ()))),
341 };
342 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
343 self.dependencies_include (&_context_path) ?;
344
345 writeln! (self.generated, "::hyper_static_server::askama! (Resource_{}, Template_{}, {{ type : {}, deserialize : ({:?}, {:?}) }}, {}, {:?}, {:?});", _id, _id, _context_type, _context_encoding, _context_path, _content_type, _template, _description) .infallible (0x35966385);
346 } else {
347 writeln! (self.generated, "::hyper_static_server::askama! (Resource_{}, Template_{}, {{ type : {} }}, {}, {:?}, {:?});", _id, _id, _context_type, _content_type, _template, _description) .infallible (0x35966385);
348 }
349 writeln! (self.generated, "::hyper_static_server::route! (Route_{}, Resource_{}, {:?}, {});", _id, _id, _route, _extensions) .infallible (0x41a5ee4c);
350
351 Ok (())
352 }
353
354
355 #[ cfg (feature = "builder-askama") ]
356 pub fn watch_askama (&mut self, _source : &str) -> BuilderResult {
357
358 let _templates_sources = self.configuration.templates_sources.as_ref () .map (PathBuf::as_path);
359 let (_relative, _source) = self.resolve_file (_templates_sources, _source) ?;
360
361 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
362 self.dependencies_include (&_source) ?;
363
364 Ok (())
365 }
366
367 #[ cfg (feature = "builder-askama") ]
368 pub fn watch_askamas (&mut self, _sources : &str, _glob : Option<&str>) -> BuilderResult {
369
370 let _templates_sources = self.configuration.templates_sources.as_ref () .map (PathBuf::as_path);
371 let (_files, _folders) = self.resolve_files (_templates_sources, _sources, _glob) ?;
372
373 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
374 self.dependencies_include_all (_folders.iter () .map (PathBuf::as_path)) ?;
375
376 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
377 self.dependencies_include_all (_files.iter () .map (|_pair| _pair.1.as_path ())) ?;
378
379 Ok (())
380 }
381
382
383
384
385 #[ cfg (feature = "builder-askama") ]
386 #[ cfg (feature = "builder-markdown") ]
387 pub fn route_markdown_askama (&mut self, _source_markdown_0 : &str, _source_template_0 : &str, _context : Option<&str>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
388
389 let _templates_sources = self.configuration.templates_sources.as_ref () .map (PathBuf::as_path);
390 let (_relative_template, _source_template) = self.resolve_file (_templates_sources, _source_template_0) ?;
391
392 let _template = _relative_template.strip_prefix ("/") .infallible (0xda5e5ad4);
393
394 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
395 self.dependencies_include (&_source_template) ?;
396
397 let _markdowns_sources = self.configuration.markdowns_sources.as_ref () .map (PathBuf::as_path);
398 let (_relative_markdown, _source_markdown) = self.resolve_file (_markdowns_sources, _source_markdown_0) ?;
399
400 let _route_base = Some (Path::new ("/"));
401
402 self.route_markdown_askama_0 (&_relative_markdown, &_source_markdown, &_template, _context, _route_base, _route_builder, _extensions_builder, _source_markdown_0, None)
403 }
404
405 #[ cfg (feature = "builder-askama") ]
406 #[ cfg (feature = "builder-markdown") ]
407 pub fn route_markdowns_askama (&mut self, _sources_markdown_0 : &str, _glob : Option<&str>, _source_template_0 : &str, _context : Option<&str>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
408
409 let _templates_sources = self.configuration.templates_sources.as_ref () .map (PathBuf::as_path);
410 let (_relative_template, _source_template) = self.resolve_file (_templates_sources, _source_template_0) ?;
411
412 let _template = _relative_template.strip_prefix ("/") .infallible (0xe0168bd3);
413
414 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
415 self.dependencies_include (&_source_template) ?;
416
417 let _markdowns_sources = self.configuration.markdowns_sources.as_ref () .map (PathBuf::as_path);
418 let (_files_markdown, _folders_markdown) = self.resolve_files (_markdowns_sources, _sources_markdown_0, _glob) ?;
419
420 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
421 self.dependencies_include_all (_folders_markdown.iter () .map (PathBuf::as_path)) ?;
422
423 let _route_base = Some (Path::new ("/"));
424
425 for (_relative_markdown, _source_markdown) in _files_markdown.into_iter () {
426
427 self.route_markdown_askama_0 (&_relative_markdown, &_source_markdown, &_template, _context, _route_base, _route_builder, _extensions_builder, _sources_markdown_0, Some (_relative_markdown.as_path ())) ?;
428 }
429
430 Ok (())
431 }
432
433
434 #[ cfg (feature = "builder-askama") ]
435 #[ cfg (feature = "builder-markdown") ]
436 fn route_markdown_askama_0 (&mut self, _relative_markdown : &Path, _source_markdown : &Path, _template : &Path, _context : Option<&str>, _route_base : Option<&Path>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized), _source_0 : &str, _source_relative : Option<&Path>) -> BuilderResult {
437
438 let _relative_markdown_1 = _relative_markdown.with_extension ("");
439
440 let (_output_body, _output_title, _output_metadata, _output_frontmatter, _refresher) = if cfg! (any (not (feature = "builder-relaxed-dependencies"), not (feature = "builder-markdown-dynamic"), not (feature = "builder-askama-dynamic"), feature = "production")) {
441
442 self.dependencies_include (_source_markdown) ?;
443
444 let _markdown = self.compile_markdown_body (_source_markdown, true) ?;
445 let _markdown_body = _markdown.body;
446 let _markdown_metadata = _markdown.metadata;
447 let _markdown_frontmatter = _markdown.frontmatter;
448
449 let _markdown_title = _markdown_metadata.title.as_ref () .map (String::as_str) .unwrap_or ("");
450
451 let _output_title = self.configuration.outputs.join (fingerprint_data (&_markdown_title)) .with_extension ("txt");
452 create_file_from_str (&_output_title, _markdown_title, true, true) ?;
453
454 let _output_body = self.configuration.outputs.join (fingerprint_data (&_markdown_body)) .with_extension ("html");
455 create_file_from_str (&_output_body, &_markdown_body, true, true) ?;
456
457 let _output_metadata = self.configuration.outputs.join (fingerprint_data (&_markdown_body)) .with_extension ("meta");
458 let _markdown_metadata = ::serde_json::to_string_pretty (&_markdown_metadata) .or_wrap (0x94fe158d) ?;
459 create_file_from_str (&_output_metadata, &_markdown_metadata, true, true) ?;
460
461 let _output_frontmatter = if let Some (_frontmatter) = _markdown_frontmatter {
462 let _encoding = _frontmatter.encoding.as_ref ();
463 let _data = _frontmatter.data.as_ref ();
464 let _extension = match _encoding {
465 "toml" => "toml",
466 "yaml" => "yaml",
467 "json" => "json",
468 _ =>
469 return Err (error_with_format (0x75f4427f, format_args! ("{}", _encoding))),
470 };
471 let _path = self.configuration.outputs.join (fingerprint_data (&_data)) .with_extension (_extension);
472 create_file_from_str (&_path, &_data, true, true) ?;
473 Some ((_extension, _path))
474 } else {
475 None
476 };
477
478 (_output_body, _output_title, _output_metadata, _output_frontmatter, false)
479
480 } else {
481
482 let _token = fingerprint_data (_source_markdown.to_string_lossy () .as_bytes ());
483
484 let _output_body = self.configuration.outputs.join (&_token) .with_extension ("html");
485
486 let _output_title = self.configuration.outputs.join (&_token) .with_extension ("txt");
487
488 let _output_metadata = self.configuration.outputs.join (&_token) .with_extension ("meta");
489
490 let _output_frontmatter = self.configuration.outputs.join (&_token) .with_extension ("data");
491
492 (_output_body, _output_title, _output_metadata, Some (("auto", _output_frontmatter)), true)
493 };
494
495 let _route = _route_builder.build (&_relative_markdown_1, _source_markdown, _route_base, None) ?;
496 let _extensions = _extensions_builder.build () ?;
497
498 let _id = self.generate_id ();
499
500 let _content_type = "html";
501 let _description = if let Some (_relative) = _source_relative {
502 format! ("markdown_askama ({}, from = `{}`, file = `...{}`)", _content_type, _source_0, _relative.display ())
503 } else {
504 format! ("markdown_askama ({}, file = `{}`)", _content_type, _source_0)
505 };
506
507 self.route_names.push (format! ("Route_{}", _id));
508
509 let _refresher_code = if _refresher {
510 let (_context_encoding, _context_path) = _output_frontmatter.as_ref () .or_panic (0xc27ad812);
511 writeln! (self.generated, "::hyper_static_server::resource_markdown_refresher! (Refresher_{}, (relative_to_cwd, {:?}), (relative_to_cwd, {:?}), (relative_to_cwd, {:?}), (relative_to_cwd, {:?}), (relative_to_cwd, {:?}));", _id, _source_markdown, _output_body, _output_title, _output_metadata, _context_path) .infallible (0x2b54879e);
512 format! ("Refresher_{},", _id)
513 } else {
514 String::new ()
515 };
516
517 if let Some ((_context_encoding, _context_path)) = _output_frontmatter {
518 if let Some (_context_type) = _context {
519 writeln! (self.generated, "::hyper_static_server::askama_document! (Resource_{}, Template_{}, {{ type : {}, deserialize : ({:?}, {:?}) }}, {}, {:?}, {:?}, {:?}, {:?}, {} {:?});", _id, _id, _context_type, _context_encoding, _context_path, _content_type, _template, _output_body, _output_title, _output_metadata, _refresher_code, _description) .infallible (0xd64341cb);
520 } else {
521 let _context_type = _context.unwrap_or ("()");
522 writeln! (self.generated, "::hyper_static_server::askama_document! (Resource_{}, Template_{}, {{ type : {} }}, {}, {:?}, {:?}, {:?}, {:?}, {} {:?});", _id, _id, _context_type, _content_type, _template, _output_body, _output_title, _output_metadata, _refresher_code, _description) .infallible (0xd64341cb);
523 }
524 } else {
525 let _context_type = _context.unwrap_or ("()");
526 writeln! (self.generated, "::hyper_static_server::askama_document! (Resource_{}, Template_{}, {{ type : {} }}, {}, {:?}, {:?}, {:?}, {:?}, {} {:?});", _id, _id, _context_type, _content_type, _template, _output_body, _output_title, _output_metadata, _refresher_code, _description) .infallible (0xd64341cb);
527 }
528
529 writeln! (self.generated, "::hyper_static_server::route! (Route_{}, Resource_{}, {:?}, {});", _id, _id, _route, _extensions) .infallible (0xafb30ea0);
530
531 Ok (())
532 }
533
534
535
536
537 #[ cfg (feature = "builder-markdown") ]
538 pub fn route_markdown (&mut self, _source_0 : &str, _header_source : Option<&str>, _footer_source : Option<&str>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
539
540 let _markdowns_sources = self.configuration.markdowns_sources.as_ref () .map (PathBuf::as_path);
541 let (_relative, _source) = self.resolve_file (_markdowns_sources, _source_0) ?;
542
543 let _route_base = Some (Path::new ("/"));
544
545 self.route_markdown_0 (&_relative, &_source, _header_source, _footer_source, _route_base, _route_builder, _extensions_builder, _source_0, None)
546 }
547
548 #[ cfg (feature = "builder-markdown") ]
549 pub fn route_markdowns (&mut self, _sources_0 : &str, _glob : Option<&str>, _header_source : Option<&str>, _footer_source : Option<&str>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
550
551 let _markdowns_sources = self.configuration.markdowns_sources.as_ref () .map (PathBuf::as_path);
552 let (_files, _folders) = self.resolve_files (_markdowns_sources, _sources_0, _glob) ?;
553
554 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
555 self.dependencies_include_all (_folders.iter () .map (PathBuf::as_path)) ?;
556
557 let _route_base = Some (Path::new ("/"));
558
559 for (_relative, _source) in _files.into_iter () {
560
561 if _source.extension () .or_wrap (0xc1ecda55) ? != "md" {
562 return Err (error_with_format (0x393ea45d, format_args! ("{}", _source.display ())));
563 }
564
565 self.route_markdown_0 (&_relative, &_source, _header_source, _footer_source, _route_base, _route_builder, _extensions_builder, _sources_0, Some (_relative.as_path ())) ?;
566 }
567
568 Ok (())
569 }
570
571
572 #[ cfg (feature = "builder-markdown") ]
573 fn route_markdown_0 (&mut self, _relative : &Path, _source : &Path, _header_source : Option<&str>, _footer_source : Option<&str>, _route_base : Option<&Path>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized), _source_0 : &str, _source_relative : Option<&Path>) -> BuilderResult {
574
575 let _markdowns_sources = self.configuration.markdowns_sources.as_ref () .map (PathBuf::as_path);
576 let _header_source = _header_source.map (|_source| BuilderResult::Ok (self.resolve_file (_markdowns_sources, _source) ? .1)) .transpose () ?;
577 let _footer_source = _footer_source.map (|_source| BuilderResult::Ok (self.resolve_file (_markdowns_sources, _source) ? .1)) .transpose () ?;
578
579 let _relative_1 = _relative.with_extension ("");
580
581 if cfg! (any (not (feature = "builder-relaxed-dependencies"), not (feature = "builder-markdown-dynamic"), feature = "production")) {
582
583 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), not (feature = "builder-markdown-dynamic"), feature = "production")) ]
584 {
585 self.dependencies_include (&_source) ?;
586 if let Some (_header_source) = &_header_source {
587 self.dependencies_include (_header_source) ?;
588 }
589 if let Some (_footer_source) = &_footer_source {
590 self.dependencies_include (_footer_source) ?;
591 }
592 }
593
594 let _header_source = _header_source.as_ref () .map (PathBuf::as_path);
595 let _footer_source = _footer_source.as_ref () .map (PathBuf::as_path);
596
597 let _html_data = self.compile_markdown_html (_source, _header_source, _footer_source) ?;
598
599 let _output = self.configuration.outputs.join (fingerprint_data (&_html_data)) .with_extension ("html");
600 create_file_from_str (&_output, &_html_data, true, true) ?;
601
602 self.route_asset_raw (&_relative_1, &_output, "html", _route_base, _route_builder, _extensions_builder, "markdown", _source_0, _source_relative) ?;
604
605 self.dependencies_exclude (&_output) ?;
606
607 } else {
608
609 let _route = _route_builder.build (&_relative_1, &_source, _route_base, None) ?;
610 let _extensions = _extensions_builder.build () ?;
611
612 let _id = self.generate_id ();
613
614 let _description = format! ("{} (file = `{}`)", "resource_markdown", _source_0);
615
616 self.route_names.push (format! ("Route_{}", _id));
617
618 writeln! (self.generated, "::hyper_static_server::resource_markdown_dynamic! (Resource_{}, {}, (relative_to_cwd, {:?}), (relative_to_cwd, {:?}), (relative_to_cwd, {:?}), {:?});", _id, "html", _source, _header_source, _footer_source, _description) .infallible (0x15f089dc);
619 writeln! (self.generated, "::hyper_static_server::route! (Route_{}, Resource_{}, {:?}, {});", _id, _id, _route, _extensions) .infallible (0xbf41dd16);
620 }
621
622 Ok (())
623 }
624
625
626
627
628 #[ cfg (feature = "builder-assets") ]
629 pub fn route_css (&mut self, _source_0 : &str, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
630
631 let _css_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
632 let (_relative, _source) = self.resolve_file (_css_sources, _source_0) ?;
633
634 let _route_base = self.configuration.css_route_base.clone ();
635 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
636
637 self.route_asset_raw (&_relative, &_source, "css", _route_base, _route_builder, _extensions_builder, "resource_css", _source_0, None)
638 }
639
640
641 #[ cfg (feature = "builder-assets") ]
642 #[ cfg (feature = "builder-assets-sass") ]
643 pub fn route_sass (&mut self, _source_0 : &str, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
644
645 let _css_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
646 let (_relative, _source) = self.resolve_file (_css_sources, _source_0) ?;
647
648 let _relative_1 = _relative.with_extension ("css");
649
650 let _route_base = self.configuration.css_route_base.clone ();
651 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
652
653 if cfg! (any (not (feature = "builder-relaxed-dependencies"), not (feature = "builder-assets-sass-dynamic"), feature = "production")) {
654
655 self.dependencies_include (&_source) ?;
656
657 let _compiled = self.compile_sass (&_source) ?;
658
659 let _output = self.configuration.outputs.join (fingerprint_data (&_compiled)) .with_extension ("css");
660 create_file_from_str (&_output, &_compiled, true, true) ?;
661
662 self.route_asset_raw (&_relative_1, &_output, "css", _route_base, _route_builder, _extensions_builder, "resource_sass", _source_0, None) ?;
664
665 self.dependencies_exclude (&_output) ?;
666
667 } else {
668
669 let _route = _route_builder.build (&_relative_1, &_source, _route_base, None) ?;
670 let _extensions = _extensions_builder.build () ?;
671
672 let _id = self.generate_id ();
673
674 let _description = format! ("{} (file = `{}`)", "resource_sass", _source_0);
675
676 self.route_names.push (format! ("Route_{}", _id));
677
678 writeln! (self.generated, "::hyper_static_server::resource_sass_dynamic! (Resource_{}, {}, (relative_to_cwd, {:?}), {:?});", _id, "css", _source, _description) .infallible (0xb7dd2208);
679 writeln! (self.generated, "::hyper_static_server::route! (Route_{}, Resource_{}, {:?}, {});", _id, _id, _route, _extensions) .infallible (0x506e8636);
680 }
681
682 Ok (())
683 }
684
685
686
687
688 #[ cfg (feature = "builder-assets") ]
689 pub fn route_js (&mut self, _source_0 : &str, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
690
691 let _js_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
692 let (_relative, _source) = self.resolve_file (_js_sources, _source_0) ?;
693
694 let _route_base = self.configuration.js_route_base.clone ();
695 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
696
697 self.route_asset_raw (&_relative, &_source, "js", _route_base, _route_builder, _extensions_builder, "resource_js", _source_0, None)
698 }
699
700
701
702
703 #[ cfg (feature = "builder-assets") ]
704 pub fn route_image (&mut self, _source_0 : &str, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
705
706 let _assets_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
707 let (_relative, _source) = self.resolve_file (_assets_sources, _source_0) ?;
708
709 let _route_base = self.configuration.images_route_base.clone ();
710 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
711
712 self.route_image_0 (&_relative, &_source, _route_base, _route_builder, _extensions_builder, "resource_image", _source_0, None)
713 }
714
715 #[ cfg (feature = "builder-assets") ]
716 pub fn route_images (&mut self, _sources_0 : &str, _glob : Option<&str>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
717
718 let _assets_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
719 let (_files, _folders) = self.resolve_files (_assets_sources, _sources_0, _glob) ?;
720
721 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
722 self.dependencies_include_all (_folders.iter () .map (PathBuf::as_path)) ?;
723
724 let _route_base = self.configuration.images_route_base.clone ();
725 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
726
727 for (_relative, _source) in _files.into_iter () {
728
729 self.route_image_0 (&_relative, &_source, _route_base, _route_builder, _extensions_builder, "resource_image", _sources_0, Some (_relative.as_path ())) ?;
730 }
731
732 Ok (())
733 }
734
735
736 #[ cfg (feature = "builder-assets") ]
737 pub fn route_icon (&mut self, _source_0 : &str, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
738
739 let _assets_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
740 let (_relative, _source) = self.resolve_file (_assets_sources, _source_0) ?;
741
742 let _route_base = self.configuration.icons_route_base.clone ();
743 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
744
745 self.route_image_0 (&_relative, &_source, _route_base, _route_builder, _extensions_builder, "resource_icon", _source_0, None)
746 }
747
748 #[ cfg (feature = "builder-assets") ]
749 pub fn route_icons (&mut self, _sources_0 : &str, _glob : Option<&str>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
750
751 let _assets_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
752 let (_files, _folders) = self.resolve_files (_assets_sources, _sources_0, _glob) ?;
753
754 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
755 self.dependencies_include_all (_folders.iter () .map (PathBuf::as_path)) ?;
756
757 let _route_base = self.configuration.icons_route_base.clone ();
758 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
759
760 for (_relative, _source) in _files.into_iter () {
761
762 self.route_image_0 (&_relative, &_source, _route_base, _route_builder, _extensions_builder, "resource_icon", _sources_0, Some (_relative.as_path ())) ?;
763 }
764
765 Ok (())
766 }
767
768
769 #[ cfg (feature = "builder-assets") ]
770 pub fn route_favicon (&mut self, _source_0 : &str, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
771
772 let _assets_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
773 let (_relative, _source) = self.resolve_file (_assets_sources, _source_0) ?;
774
775 let _route_base = self.configuration.favicons_route_base.clone ();
776 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
777
778 self.route_image_0 (&_relative, &_source, _route_base, _route_builder, _extensions_builder, "resource_favicon", _source_0, None)
779 }
780
781 #[ cfg (feature = "builder-assets") ]
782 pub fn route_favicons (&mut self, _sources_0 : &str, _glob : Option<&str>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
783
784 let _assets_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
785 let (_files, _folders) = self.resolve_files (_assets_sources, _sources_0, _glob) ?;
786
787 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
788 self.dependencies_include_all (_folders.iter () .map (PathBuf::as_path)) ?;
789
790 let _route_base = self.configuration.favicons_route_base.clone ();
791 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
792
793 for (_relative, _source) in _files.into_iter () {
794
795 self.route_image_0 (&_relative, &_source, _route_base, _route_builder, _extensions_builder, "resource_favicon", _sources_0, Some (_relative.as_path ())) ?;
796 }
797
798 Ok (())
799 }
800
801
802 #[ cfg (feature = "builder-assets") ]
803 fn route_image_0 (&mut self, _relative : &Path, _source : &Path, _route_base : Option<&Path>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized), _macro : &str, _source_0 : &str, _source_relative : Option<&Path>) -> BuilderResult {
804
805 let _content_type = detect_content_type_from_extension (&_source) ?;
806 match _content_type {
807 "png" | "jpeg" | "icon" | "svg" =>
808 (),
809 _ =>
810 return Err (error_with_format (0x0fd2d804, format_args! ("{}", _source.display ()))),
811 };
812
813 self.route_asset_raw (_relative, _source, _content_type, _route_base, _route_builder, _extensions_builder, _macro, _source_0, _source_relative)
814 }
815
816
817
818
819 #[ cfg (feature = "builder-assets") ]
820 pub fn route_font (&mut self, _source_0 : &str, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
821
822 let _assets_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
823 let (_relative, _source) = self.resolve_file (_assets_sources, _source_0) ?;
824
825 let _route_base = self.configuration.fonts_route_base.clone ();
826 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
827
828 self.route_font_0 (&_relative, &_source, _route_base, _route_builder, _extensions_builder, _source_0, None)
829 }
830
831 #[ cfg (feature = "builder-assets") ]
832 pub fn route_fonts (&mut self, _sources_0 : &str, _glob : Option<&str>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
833
834 let _assets_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
835 let (_files, _folders) = self.resolve_files (_assets_sources, _sources_0, _glob) ?;
836
837 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
838 self.dependencies_include_all (_folders.iter () .map (PathBuf::as_path)) ?;
839
840 let _route_base = self.configuration.fonts_route_base.clone ();
841 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
842
843 for (_relative, _source) in _files.into_iter () {
844
845 self.route_font_0 (&_relative, &_source, _route_base, _route_builder, _extensions_builder, _sources_0, Some (_relative.as_path ())) ?;
846 }
847
848 Ok (())
849 }
850
851
852 #[ cfg (feature = "builder-assets") ]
853 fn route_font_0 (&mut self, _relative : &Path, _source : &Path, _route_base : Option<&Path>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized), _source_0 : &str, _source_relative : Option<&Path>) -> BuilderResult {
854
855 let _content_type = detect_content_type_from_extension (&_source) ?;
856 match _content_type {
857 "font_ttf" | "font_otf" | "font_woff" | "font_woff2" =>
858 (),
859 _ =>
860 return Err (error_with_format (0x1a4ccbf4, format_args! ("{}", _source.display ()))),
861 };
862
863 self.route_asset_raw (_relative, _source, _content_type, _route_base, _route_builder, _extensions_builder, "resource_font", _source_0, _source_relative)
864 }
865
866
867
868
869 #[ cfg (feature = "builder-assets") ]
870 pub fn route_asset (&mut self, _source_0 : &str, _content_type : Option<&str>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
871
872 let _assets_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
873 let (_relative, _source) = self.resolve_file (_assets_sources, _source_0) ?;
874
875 let _route_base = self.configuration.assets_route_base.clone ();
876 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
877
878 self.route_asset_0 (&_relative, &_source, _content_type, _route_base, _route_builder, _extensions_builder, _source_0, None)
879 }
880
881 #[ cfg (feature = "builder-assets") ]
882 pub fn route_assets (&mut self, _sources_0 : &str, _glob : Option<&str>, _content_type : Option<&str>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
883
884 let _assets_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
885 let (_files, _folders) = self.resolve_files (_assets_sources, _sources_0, _glob) ?;
886
887 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
888 self.dependencies_include_all (_folders.iter () .map (PathBuf::as_path)) ?;
889
890 let _route_base = self.configuration.assets_route_base.clone ();
891 let _route_base = _route_base.as_ref () .map (PathBuf::as_path);
892
893 for (_relative, _source) in _files.into_iter () {
894
895 self.route_asset_0 (&_relative, &_source, _content_type, _route_base, _route_builder, _extensions_builder, _sources_0, Some (_relative.as_path ())) ?;
896 }
897
898 Ok (())
899 }
900
901
902 #[ cfg (feature = "builder-assets") ]
903 fn route_asset_0 (&mut self, _relative : &Path, _source : &Path, _content_type : Option<&str>, _route_base : Option<&Path>, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized), _source_0 : &str, _source_relative : Option<&Path>) -> BuilderResult {
904
905 let _content_type = _content_type.map_or_else (|| detect_content_type_from_extension (&_source), |_content_type| Ok (_content_type)) ?;
906
907 self.route_asset_raw (_relative, _source, _content_type, _route_base, _route_builder, _extensions_builder, "resource_asset", _source_0, _source_relative)
908 }
909
910
911
912
913 #[ cfg (feature = "builder-sitemaps") ]
914 pub fn route_sitemap (&mut self, _prefix : &str, _format : &str, _route_builder : &(impl RoutePathBuilder + ?Sized), _extensions_builder : &(impl RouteExtensionsBuilder + ?Sized)) -> BuilderResult {
915
916 let _route = _route_builder.build (Path::new (""), Path::new (""), None, None) ?;
917 let _extensions = _extensions_builder.build () ?;
918 let _format = token_tree_parse (_format) ?;
919
920 let _id = self.generate_id ();
921
922 self.route_names.push (format! ("Route_{}", _id));
923
924 writeln! (self.generated, "::hyper_static_server::route_sitemap! (Route_{}, {:?}, {:?}, {}, {});", _id, _route, _prefix, _format, _extensions) .infallible (0x5f529a53);
925
926 Ok (())
927 }
928
929
930
931
932 #[ cfg (feature = "builder-assets") ]
933 pub fn watch_asset (&mut self, _source : &str) -> BuilderResult {
934
935 let _assets_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
936 let (_relative, _source) = self.resolve_file (_assets_sources, _source) ?;
937
938 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
939 self.dependencies_include (&_source) ?;
940
941 Ok (())
942 }
943
944 #[ cfg (feature = "builder-assets") ]
945 pub fn watch_assets (&mut self, _sources : &str, _glob : Option<&str>) -> BuilderResult {
946
947 let _assets_sources = self.configuration.assets_sources.as_ref () .map (PathBuf::as_path);
948 let (_files, _folders) = self.resolve_files (_assets_sources, _sources, _glob) ?;
949
950 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
951 self.dependencies_include_all (_folders.iter () .map (PathBuf::as_path)) ?;
952
953 #[ cfg (any (not (feature = "builder-relaxed-dependencies"), feature = "production")) ]
954 self.dependencies_include_all (_files.iter () .map (|_pair| _pair.1.as_path ())) ?;
955
956 Ok (())
957 }
958
959
960
961
962 pub fn generate (mut self) -> BuilderResult {
963
964 self.dependencies_extend () ?;
965
966 writeln! (self.generated, "::hyper_static_server::routes! (Routes, [") .infallible (0x4bf5618f);
967 for _route_name in self.route_names.into_iter () {
968 writeln! (self.generated, "\t{},", _route_name) .infallible (0x894377dd);
969 }
970 writeln! (self.generated, "]);") .infallible (0x28d1ed4d);
971
972 writeln! (self.generated, "::hyper_static_server::dependencies! (Dependencies, [") .infallible (0x1a6c02cd);
973 for _dependency in self.dependencies.iter () {
974 writeln! (self.generated, "\t{:?},", _dependency) .infallible (0x9df69eb7);
975 }
976 writeln! (self.generated, "]);") .infallible (0x57d05438);
977
978 create_file_from_str (&self.configuration.generated, &self.generated, false, true) ?;
979
980 if false {
981 eprintln! ("--------------------------------------------------------------------------------");
982 eprintln! ("{}", self.generated);
983 eprintln! ("--------------------------------------------------------------------------------");
984 }
985
986 for _dependency in self.dependencies {
987 println! ("cargo:rerun-if-changed={}", _dependency.display ());
988 }
989
990 Ok (())
991 }
992}
993
994
995
996
997impl Builder {
998
999
1000 fn resolve_file (&self, _root : Option<&Path>, _source : &str) -> BuilderResult<(PathBuf, PathBuf)> {
1001
1002 let (_path, _relative_root) = self.resolve_source (_root, _source, true) ?;
1003
1004 if ! _path.is_file () {
1005 return Err (error_with_format (0x039d945b, format_args! ("{}", _path.display ())));
1006 }
1007
1008 self.resolve_relative_and_path (&_path, &_relative_root)
1009 }
1010
1011
1012 fn resolve_files (&self, _root : Option<&Path>, _sources : &str, _glob : Option<&str>) -> BuilderResult<(Vec<(PathBuf, PathBuf)>, Vec<PathBuf>)> {
1013
1014 let (_root, _relative_root) = self.resolve_source (_root, _sources, false) ?;
1015
1016 if ! _root.is_dir () {
1017 return Err (error_with_code (0x621693a6));
1018 }
1019
1020 let _glob = _glob.map (|_pattern| globset::Glob::new (_pattern) .or_wrap (0xf68023ce)) .transpose () ?;
1021 let _glob = _glob.map (|_pattern| _pattern.compile_matcher ());
1022
1023 let mut _files = Vec::new ();
1024 let mut _folders = Vec::new ();
1025
1026 let _walker = walkdir::WalkDir::new (&_root)
1027 .follow_links (true)
1028 .sort_by (|_left, _right| ffi::OsStr::cmp (_left.file_name (), _right.file_name ()));
1029
1030 for _entry in _walker {
1031 let _entry = _entry ?;
1032 let _path = _entry.path ();
1033
1034 if _path.is_file () {
1035
1036 if let Some (_glob) = _glob.as_ref () {
1037 if ! _glob.is_match (_path) {
1038 continue;
1039 }
1040 }
1041
1042 let _relative_and_path = self.resolve_relative_and_path (_path, &_relative_root) ?;
1043
1044 _files.push (_relative_and_path);
1045 }
1046
1047 if _path.is_dir () {
1048
1049 let _path = normalize_path (_path) ?;
1050
1051 _folders.push (_path);
1052 }
1053 }
1054
1055 Ok ((_files, _folders))
1056 }
1057
1058
1059 fn resolve_source (&self, _root : Option<&Path>, _source : &str, _name_only : bool) -> BuilderResult<(PathBuf, PathBuf)> {
1060
1061 let _path = if _source.starts_with ("_/") || (_source == "_") {
1062 let _root = _root.or_wrap (0x6e3319c9) ?;
1063 if _source != "_" {
1064 _root.join (&_source[2..])
1065 } else {
1066 _root.to_owned ()
1067 }
1068
1069 } else if _source.starts_with ("./") || _source.starts_with ("..") || (_source == ".") || (_source == "..") {
1070 let _root = self.configuration.sources.as_ref () .or_wrap (0x0791a9b4) ?;
1071 _root.join (&_source)
1072
1073 } else if _source.starts_with (">") {
1074 PathBuf::from (&_source[1..])
1075
1076 } else {
1077 return Err (error_with_code (0x41071330));
1078 };
1079
1080 if ! _path.exists () {
1081 return Err (error_with_format (0x1086bd9d, format_args! ("{}", _path.display ())));
1082 }
1083
1084 if _name_only {
1085 let _relative_root = _path.parent () .or_wrap (0x067a2cad) ? .to_path_buf ();
1086 Ok ((_path, _relative_root))
1087 } else {
1088 Ok ((_path.clone (), _path))
1089 }
1090 }
1091
1092
1093 fn resolve_relative_and_path (&self, _path : &Path, _relative_root : &Path) -> BuilderResult<(PathBuf, PathBuf)> {
1094
1095 let _relative = _path.strip_prefix (_relative_root) .or_wrap (0x546e7cd9) ? .to_str () .or_wrap (0xa48f283c) ?;
1096 let _relative = ["/", _relative].concat () .into ();
1097
1098 let _path = normalize_path (&_path) ?;
1099
1100 Ok ((_relative, _path))
1101 }
1102}
1103
1104
1105
1106
1107impl Builder {
1108
1109
1110 fn dependencies_include (&mut self, _path : &Path) -> BuilderResult {
1111
1112 self.dependencies.insert (_path.into ());
1113
1114 Ok (())
1115 }
1116
1117 fn dependencies_include_all <'a> (&mut self, _paths : impl Iterator<Item = &'a Path>) -> BuilderResult {
1118
1119 for _path in _paths {
1120 self.dependencies_include (_path) ?;
1121 }
1122
1123 Ok (())
1124 }
1125
1126 #[ allow (dead_code) ]
1127 fn dependencies_exclude (&mut self, _path : &Path) -> BuilderResult {
1128
1129 self.dependencies.remove (_path.into ());
1130
1131 Ok (())
1132 }
1133
1134 fn dependencies_extend (&mut self) -> BuilderResult {
1135
1136 let mut _extra = Vec::new ();
1137
1138 for _dependency in self.dependencies.iter () {
1139
1140 let _metadata = fs::symlink_metadata (_dependency) .or_wrap (0x06a4fbd5) ?;
1141
1142 if _metadata.file_type () .is_symlink () {
1143 let _target = _dependency.canonicalize () .or_wrap (0x8df4310e) ?;
1144 _extra.push (_target);
1145 }
1146 }
1147
1148 for _dependency in _extra.into_iter () {
1149 self.dependencies.insert (_dependency);
1150 }
1151
1152 self.dependencies.insert (PathBuf::from (file! ()));
1153
1154 Ok (())
1155 }
1156}
1157
1158
1159
1160
1161impl Builder {
1162
1163
1164 fn generate_id (&mut self) -> String {
1165 let _id = self.counter;
1166 self.counter += 1;
1167 format! ("{:04}", _id)
1168 }
1169}
1170
1171
1172
1173
1174#[ cfg (feature = "builder-assets-sass") ]
1175impl Builder {
1176
1177
1178 fn compile_sass (&mut self, _source : &Path) -> BuilderResult<String> {
1179 crate::support_sass::compile_sass (_source)
1180 }
1181}
1182
1183
1184
1185
1186#[ cfg (feature = "builder-markdown") ]
1187impl Builder {
1188
1189 fn compile_markdown_body (&self, _source : &Path, _title_detect : bool) -> BuilderResult<crate::support_markdown::MarkdownOutput> {
1190 let mut _options = crate::support_markdown::MarkdownOptions::default ();
1191 _options.title_detect = _title_detect;
1192 crate::support_markdown::compile_markdown_from_path (_source, Some (&_options))
1193 }
1194
1195 fn compile_markdown_html (&self, _source : &Path, _header : Option<&Path>, _footer : Option<&Path>) -> BuilderResult<String> {
1196 crate::support_markdown::compile_markdown_html_from_path (_source, _header, _footer, None)
1197 }
1198}
1199
1200
1201
1202
1203fn create_file_from_str (_path : &Path, _data : &str, _skip_if_exists : bool, _skip_if_same : bool) -> BuilderResult {
1204
1205 fs::create_dir_all (_path.parent () .or_wrap (0x370af23d) ?) ?;
1206
1207 let _metadata = match fs::symlink_metadata (_path) {
1208 Ok (_metadata) =>
1209 if _metadata.is_file () {
1210 Some (_metadata)
1211 } else {
1212 return Err (error_with_format (0x7b58f13c, format_args! ("{}", _path.display ())));
1213 }
1214 Err (_error) if _error.kind () == io::ErrorKind::NotFound =>
1215 None,
1216 Err (_error) =>
1217 return Err (_error.wrap (0xb30cd904)),
1218 };
1219 if _skip_if_exists && _metadata.is_some () {
1220 return Ok (());
1221 }
1222 if _skip_if_same && _metadata.is_some () {
1223 let _data_old = fs::read (_path) .or_wrap (0x6c311b95) ?;
1224 let _data_old_fingerprint = fingerprint_data (_data_old);
1225 let _data_new_fingerprint = fingerprint_data (_data);
1226 if _data_old_fingerprint == _data_new_fingerprint {
1227 return Ok (());
1228 }
1229 }
1230
1231 let mut _file = fs::File::create (_path) ?;
1233 _file.write_all (_data.as_bytes ()) ?;
1234
1235 Ok (())
1236}
1237
1238
1239
1240
1241pub trait RoutePathBuilder {
1242
1243 fn build (&self, _source_relative : &Path, _source_path : &Path, _route_prefix_hint : Option<&Path>, _route_infix_hint : Option<&Path>) -> BuilderResult<PathBuf>;
1244}
1245
1246
1247impl RoutePathBuilder for () {
1248
1249 fn build (&self, _source_relative : &Path, _source_path : &Path, _route_prefix_hint : Option<&Path>, _route_infix_hint : Option<&Path>) -> BuilderResult<PathBuf> {
1250 generate_route (_source_relative, _route_prefix_hint, _route_infix_hint)
1251 }
1252}
1253
1254
1255impl RoutePathBuilder for (bool, &str) {
1256
1257 fn build (&self, _source_relative : &Path, _source_path : &Path, _route_prefix_hint : Option<&Path>, _route_infix_hint : Option<&Path>) -> BuilderResult<PathBuf> {
1258 if self.0 {
1259 generate_route (_source_relative, Some (Path::new (self.1)), None)
1260 } else {
1261 normalize_route (Path::new (self.1), true, false)
1262 }
1263 }
1264}
1265
1266
1267
1268
1269pub trait RouteExtensionsBuilder {
1270
1271 fn build (&self) -> BuilderResult<proc_macro2::TokenTree>;
1272}
1273
1274
1275impl RouteExtensionsBuilder for () {
1276
1277 fn build (&self) -> BuilderResult<proc_macro2::TokenTree> {
1278 Ok (proc_macro2::Group::new (proc_macro2::Delimiter::Parenthesis, proc_macro2::TokenStream::new ()) .into ())
1279 }
1280}
1281
1282
1283impl RouteExtensionsBuilder for str {
1284
1285 fn build (&self) -> BuilderResult<proc_macro2::TokenTree> {
1286 token_tree_parse (self)
1287 }
1288}
1289
1290
1291
1292
1293fn generate_route (_source_relative : &Path, _route_prefix : Option<&Path>, _route_infix : Option<&Path>) -> BuilderResult<PathBuf> {
1294
1295 let _route_prefix = _route_prefix.or_wrap (0x1ba00780) ?;
1296
1297 if ! _route_prefix.starts_with ("/") || (_route_prefix.ends_with ("/") && _route_prefix != Path::new ("/")) {
1298 return Err (error_with_code (0x6fc9256c));
1299 }
1300 if ! _source_relative.starts_with ("/") || _source_relative.ends_with ("/") {
1301 return Err (error_with_code (0xace09af4));
1302 }
1303 if let Some (_route_infix) = _route_infix {
1304 if _route_infix.starts_with ("/") || _route_infix.ends_with ("/") {
1305 return Err (error_with_code (0xd224b592));
1306 }
1307 }
1308
1309 let _source_relative = _source_relative.strip_prefix ("/") .or_wrap (0xbd4b80bd) ?;
1310
1311 let _route = if let Some (_route_infix) = _route_infix {
1312 let _route_infix = _route_infix.strip_prefix ("/") .or_wrap (0x1a7e3353) ?;
1313 _route_prefix.join (_route_infix) .join (_source_relative)
1314 } else {
1315 _route_prefix.join (_source_relative)
1316 };
1317
1318 normalize_route (&_route, false, false)
1319}
1320
1321
1322fn normalize_route (_path_0 : &Path, _keep_trailing_slash : bool, _force_trailing_slash : bool) -> BuilderResult<PathBuf> {
1323
1324 if ! _path_0.starts_with ("/") {
1325 return Err (error_with_code (0x1e7f7bc0));
1326 }
1327
1328 let mut _path = PathBuf::new ();
1329 _path.push ("/");
1330 for _component in _path_0.components () {
1331 _path.push (_component);
1332 }
1333
1334 if (_keep_trailing_slash || _force_trailing_slash) && (_path != Path::new ("/")) {
1335 if _path_0.to_string_lossy () .ends_with ("/") || _force_trailing_slash {
1336 let mut _path_1 = _path.clone () .into_os_string ();
1337 _path_1.push ("/");
1338 _path = _path_1.into ();
1339 }
1340 }
1341
1342 Ok (_path)
1343}
1344
1345
1346fn normalize_path (_path_0 : &Path) -> BuilderResult<PathBuf> {
1347
1348 let mut _path = PathBuf::new ();
1349 for _component in _path_0.components () {
1350 _path.push (_component);
1351 }
1352
1353 Ok (_path)
1354}
1355
1356
1357
1358
1359fn detect_content_type_from_extension (_source : &Path) -> BuilderResult<&'static str> {
1360
1361 let _extension = _source.extension () .or_wrap (0x29957dc8) ? .to_str () .or_wrap (0x908aeea6) ?;
1362
1363 let _content_type = match _extension {
1364 "text" | "txt" => "text",
1365 "md" => "text",
1366 "html" | "htm" => "html",
1367 "css" => "css",
1368 "js" => "js",
1369 "json" => "json",
1370 "xml" => "xml",
1371 "png" => "png",
1372 "jpeg" | "jpg" => "jpeg",
1373 "ico" => "icon",
1374 "svg" => "svg",
1375 "ttf" => "font_ttf",
1376 "otf" => "font_otf",
1377 "woff" => "font_woff",
1378 "woff2" => "font_woff2",
1379 _ => "unknown",
1380 };
1381
1382 Ok (_content_type)
1383}
1384
1385
1386
1387
1388fn token_tree_parse (_string : &str) -> BuilderResult<proc_macro2::TokenTree> {
1389 let _stream = proc_macro2::TokenStream::from_str (_string) .or_wrap (0x72524db6) ?;
1390 let mut _stream = _stream.into_iter ();
1391 let _token = if let Some (_token) = _stream.next () {
1392 _token
1393 } else {
1394 return Err (error_with_code (0xe9c8879a))
1395 };
1396 if _stream.next () .is_some () {
1397 return Err (error_with_code (0xd96714a4))
1398 }
1399 Ok (_token)
1400}
1401
1402
1403
1404
1405#[ allow (dead_code) ]
1406fn fingerprint_data (_data : impl AsRef<[u8]>) -> String {
1407 use blake2::Digest as _;
1408 let mut _hasher = blake2::Blake2b::new ();
1409 _hasher.update (_data.as_ref ());
1410 let _hash = _hasher.finalize ();
1411 format! ("{:x}", _hash)
1412}
1413