11//! Support for writing static files.
22
33use log:: { debug, warn} ;
4+ use once_cell:: sync:: Lazy ;
45
56use crate :: config:: HtmlConfig ;
67use crate :: errors:: * ;
@@ -231,27 +232,32 @@ impl StaticFiles {
231232 use std:: io:: Read ;
232233 // The `{{ resource "name" }}` directive in static resources look like
233234 // handlebars syntax, even if they technically aren't.
234- let resource = Regex :: new ( r#"\{\{ resource "([^"]+)" \}\}"# ) . unwrap ( ) ;
235- for static_file in self . static_files {
235+ static RESOURCE : Lazy < Regex > =
236+ Lazy :: new ( || Regex :: new ( r#"\{\{ resource "([^"]+)" \}\}"# ) . unwrap ( ) ) ;
237+ fn replace_all < ' a > (
238+ hash_map : & HashMap < String , String > ,
239+ data : & ' a [ u8 ] ,
240+ filename : & str ,
241+ ) -> Cow < ' a , [ u8 ] > {
242+ RESOURCE . replace_all ( data, move |captures : & Captures < ' _ > | {
243+ let name = captures
244+ . get ( 1 )
245+ . expect ( "capture 1 in resource regex" )
246+ . as_bytes ( ) ;
247+ let name = std:: str:: from_utf8 ( name) . expect ( "resource name with invalid utf8" ) ;
248+ let resource_filename = hash_map. get ( name) . map ( |s| & s[ ..] ) . unwrap_or ( & name) ;
249+ let path_to_root = utils:: fs:: path_to_root ( & filename) ;
250+ format ! ( "{}{}" , path_to_root, resource_filename)
251+ . as_bytes ( )
252+ . to_owned ( )
253+ } )
254+ }
255+ for static_file in & self . static_files {
236256 match static_file {
237257 StaticFile :: Builtin { filename, data } => {
238258 debug ! ( "Writing builtin -> {}" , filename) ;
239- let hash_map = & self . hash_map ;
240259 let data = if filename. ends_with ( ".css" ) || filename. ends_with ( ".js" ) {
241- resource. replace_all ( & data, |captures : & Captures < ' _ > | {
242- let name = captures
243- . get ( 1 )
244- . expect ( "capture 1 in resource regex" )
245- . as_bytes ( ) ;
246- let name =
247- std:: str:: from_utf8 ( name) . expect ( "resource name with invalid utf8" ) ;
248- let resource_filename =
249- hash_map. get ( name) . map ( |s| & s[ ..] ) . unwrap_or ( & name) ;
250- let path_to_root = utils:: fs:: path_to_root ( & filename) ;
251- format ! ( "{}{}" , path_to_root, resource_filename)
252- . as_bytes ( )
253- . to_owned ( )
254- } )
260+ replace_all ( & self . hash_map , data, filename)
255261 } else {
256262 Cow :: Borrowed ( & data[ ..] )
257263 } ;
@@ -272,25 +278,11 @@ impl StaticFiles {
272278 . with_context ( || format ! ( "Unable to create {}" , parent. display( ) ) ) ?;
273279 }
274280 if filename. ends_with ( ".css" ) || filename. ends_with ( ".js" ) {
275- let hash_map = & self . hash_map ;
276281 let mut file = File :: open ( input_location) ?;
277282 let mut data = Vec :: new ( ) ;
278283 file. read_to_end ( & mut data) ?;
279- let data = resource. replace_all ( & data, |captures : & Captures < ' _ > | {
280- let name = captures
281- . get ( 1 )
282- . expect ( "capture 1 in resource regex" )
283- . as_bytes ( ) ;
284- let name =
285- std:: str:: from_utf8 ( name) . expect ( "resource name with invalid utf8" ) ;
286- let resource_filename =
287- hash_map. get ( name) . map ( |s| & s[ ..] ) . unwrap_or ( & name) ;
288- let path_to_root = utils:: fs:: path_to_root ( & filename) ;
289- format ! ( "{}{}" , path_to_root, resource_filename)
290- . as_bytes ( )
291- . to_owned ( )
292- } ) ;
293- write_file ( destination, & filename, & data) ?;
284+ let data = replace_all ( & self . hash_map , & data, filename) ;
285+ write_file ( destination, filename, & data) ?;
294286 } else {
295287 fs:: copy ( & input_location, & output_location) . with_context ( || {
296288 format ! (
0 commit comments