Refactor handling of generated unique names for resources

This commit is contained in:
Magnus Hoff 2018-06-24 23:00:35 +02:00
parent 77210a9692
commit 0b5bff6356
8 changed files with 35 additions and 28 deletions

View file

@ -49,6 +49,14 @@ pub fn static_resource(input: TokenStream) -> TokenStream {
let checksum = calculate_checksum(&abs_filename); let checksum = calculate_checksum(&abs_filename);
let path: &Path = filename.as_ref();
let resource_name =
format!("{}-{}.{}",
path.file_stem().unwrap().to_str().unwrap(),
checksum,
path.extension().unwrap().to_str().unwrap()
);
let mime = find_attr(&ast.attrs, "mime") let mime = find_attr(&ast.attrs, "mime")
.expect("The `mime` attribute must be specified"); .expect("The `mime` attribute must be specified");
@ -90,12 +98,12 @@ pub fn static_resource(input: TokenStream) -> TokenStream {
} }
impl #impl_generics #name #ty_generics #where_clause { impl #impl_generics #name #ty_generics #where_clause {
pub fn checksum() -> &'static str { pub fn resource_name() -> &'static str {
#checksum #resource_name
} }
pub fn etag() -> ::hyper::header::EntityTag { pub fn etag() -> ::hyper::header::EntityTag {
::hyper::header::EntityTag::new(false, Self::checksum().to_owned()) ::hyper::header::EntityTag::new(false, #checksum.to_owned())
} }
} }
}; };

View file

@ -29,8 +29,8 @@ struct Template<'a> {
} }
impl<'a> Template<'a> { impl<'a> Template<'a> {
fn script_js_checksum(&self) -> &'static str { fn script_js(&self) -> &'static str {
ScriptJs::checksum() ScriptJs::resource_name()
} }
} }

View file

@ -69,8 +69,8 @@ impl Resource for NewArticleResource {
rendered: &'a str, rendered: &'a str,
} }
impl<'a> Template<'a> { impl<'a> Template<'a> {
fn script_js_checksum(&self) -> &'static str { fn script_js(&self) -> &'static str {
ScriptJs::checksum() ScriptJs::resource_name()
} }
} }

View file

@ -9,7 +9,7 @@ use hyper::mime;
use hyper::server::*; use hyper::server::*;
use hyper; use hyper;
use assets::{StyleCss, SearchJs}; use assets::{ThemesCss, StyleCss, SearchJs};
use build_config; use build_config;
use web::Lookup; use web::Lookup;
use wiki_lookup::WikiLookup; use wiki_lookup::WikiLookup;
@ -41,8 +41,9 @@ impl<'a, T: 'a + fmt::Display> Layout<'a, T> {
THEMES[choice] THEMES[choice]
} }
pub fn style_css_checksum(&self) -> &str { StyleCss::checksum() } pub fn themes_css(&self) -> &str { ThemesCss::resource_name() }
pub fn search_js_checksum(&self) -> &str { SearchJs::checksum() } pub fn style_css(&self) -> &str { StyleCss::resource_name() }
pub fn search_js(&self) -> &str { SearchJs::resource_name() }
pub fn project_name(&self) -> &str { build_config::PROJECT_NAME } pub fn project_name(&self) -> &str { build_config::PROJECT_NAME }
pub fn version(&self) -> &str { build_config::VERSION.as_str() } pub fn version(&self) -> &str { build_config::VERSION.as_str() }

View file

@ -16,38 +16,35 @@ type BoxResource = Box<Resource + Sync + Send>;
type ResourceFn = Box<Fn() -> BoxResource + Sync + Send>; type ResourceFn = Box<Fn() -> BoxResource + Sync + Send>;
lazy_static! { lazy_static! {
static ref ASSETS_MAP: HashMap<String, ResourceFn> = hashmap!{ static ref ASSETS_MAP: HashMap<&'static str, ResourceFn> = hashmap!{
// The CSS should be built to a single CSS file at compile time // The CSS should be built to a single CSS file at compile time
"themes.css".into() => ThemesCss::resource_name() =>
Box::new(|| Box::new(ThemesCss) as BoxResource) as ResourceFn, Box::new(|| Box::new(ThemesCss) as BoxResource) as ResourceFn,
format!("style-{}.css", StyleCss::checksum()) => StyleCss::resource_name() =>
Box::new(|| Box::new(StyleCss) as BoxResource) as ResourceFn, Box::new(|| Box::new(StyleCss) as BoxResource) as ResourceFn,
format!("script-{}.js", ScriptJs::checksum()) => ScriptJs::resource_name() =>
Box::new(|| Box::new(ScriptJs) as BoxResource) as ResourceFn, Box::new(|| Box::new(ScriptJs) as BoxResource) as ResourceFn,
format!("search-{}.js", SearchJs::checksum()) => SearchJs::resource_name() =>
Box::new(|| Box::new(SearchJs) as BoxResource) as ResourceFn, Box::new(|| Box::new(SearchJs) as BoxResource) as ResourceFn,
format!("amatic-sc-v9-latin-regular.woff") =>
Box::new(|| Box::new(AmaticFont) as BoxResource) as ResourceFn,
}; };
static ref LICENSES_MAP: HashMap<String, ResourceFn> = hashmap!{ static ref LICENSES_MAP: HashMap<&'static str, ResourceFn> = hashmap!{
"bsd-3-clause".to_owned() => Box::new(|| Box::new( "bsd-3-clause" => Box::new(|| Box::new(
HtmlResource::new(Some("../"), "The 3-Clause BSD License", include_str!("licenses/bsd-3-clause.html")) HtmlResource::new(Some("../"), "The 3-Clause BSD License", include_str!("licenses/bsd-3-clause.html"))
) as BoxResource) as ResourceFn, ) as BoxResource) as ResourceFn,
"gpl3".to_owned() => Box::new(|| Box::new( "gpl3" => Box::new(|| Box::new(
HtmlResource::new(Some("../"), "GNU General Public License", include_str!("licenses/gpl3.html")) HtmlResource::new(Some("../"), "GNU General Public License", include_str!("licenses/gpl3.html"))
) as BoxResource) as ResourceFn, ) as BoxResource) as ResourceFn,
"mit".to_owned() => Box::new(|| Box::new( "mit" => Box::new(|| Box::new(
HtmlResource::new(Some("../"), "The MIT License", include_str!("licenses/mit.html")) HtmlResource::new(Some("../"), "The MIT License", include_str!("licenses/mit.html"))
) as BoxResource) as ResourceFn, ) as BoxResource) as ResourceFn,
"mpl2".to_owned() => Box::new(|| Box::new( "mpl2" => Box::new(|| Box::new(
HtmlResource::new(Some("../"), "Mozilla Public License Version 2.0", include_str!("licenses/mpl2.html")) HtmlResource::new(Some("../"), "Mozilla Public License Version 2.0", include_str!("licenses/mpl2.html"))
) as BoxResource) as ResourceFn, ) as BoxResource) as ResourceFn,
"sil-ofl-1.1".to_owned() => Box::new(|| Box::new( "sil-ofl-1.1" => Box::new(|| Box::new(
HtmlResource::new(Some("../"), "SIL Open Font License", include_str!("licenses/sil-ofl-1.1.html")) HtmlResource::new(Some("../"), "SIL Open Font License", include_str!("licenses/sil-ofl-1.1.html"))
) as BoxResource) as ResourceFn, ) as BoxResource) as ResourceFn,
}; };
@ -70,7 +67,7 @@ fn split_one(path: &str) -> Result<(Cow<str>, Option<&str>), Utf8Error> {
Ok((head, tail)) Ok((head, tail))
} }
fn map_lookup(map: &HashMap<String, ResourceFn>, path: &str) -> fn map_lookup(map: &HashMap<&str, ResourceFn>, path: &str) ->
FutureResult<Option<BoxResource>, Box<::std::error::Error + Send + Sync>> FutureResult<Option<BoxResource>, Box<::std::error::Error + Send + Sync>>
{ {
let (head, tail) = match split_one(path) { let (head, tail) = match split_one(path) {

View file

@ -1,4 +1,4 @@
<script src="_assets/script-{{script_js_checksum()}}.js" defer></script> <script src="_assets/{{script_js()}}" defer></script>
<div class="container {{#edit?}}edit{{/edit}}"> <div class="container {{#edit?}}edit{{/edit}}">
<div class="rendered"> <div class="rendered">

View file

@ -5,7 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8"> <meta charset="utf-8">
{{#base}}<base href="{{.}}">{{/base}} {{#base}}<base href="{{.}}">{{/base}}
<link href="_assets/style-{{style_css_checksum()}}.css" rel="stylesheet"> <link href="_assets/{{themes_css()}}" rel="stylesheet">
<link href="_assets/{{style_css()}}" rel="stylesheet">
<meta name="generator" content="{{project_name()}} {{version()}}" /> <meta name="generator" content="{{project_name()}} {{version()}}" />
</head> </head>
<body class="theme-{{theme()}}"> <body class="theme-{{theme()}}">

View file

@ -7,5 +7,5 @@
</div> </div>
</form> </form>
<ul id="search-result-prototype" class="prototype"><li class="search-result"><a tabindex="0" class="link" href=""><span class="title"></span> &ndash; <span class="snippet"></span></a></li></ul> <ul id="search-result-prototype" class="prototype"><li class="search-result"><a tabindex="0" class="link" href=""><span class="title"></span> &ndash; <span class="snippet"></span></a></li></ul>
<script src="_assets/search-{{search_js_checksum()}}.js" defer></script> <script src="_assets/{{search_js()}}" defer></script>
</div> </div>