clippy + fmt + fix toml dates in extra arrays

Closes #1048
This commit is contained in:
Vincent Prouillet 2020-06-18 21:11:22 +02:00
parent 5e31a32166
commit ade442a487
16 changed files with 171 additions and 96 deletions

104
Cargo.lock generated
View file

@ -2,9 +2,9 @@
# It is not intended for manual editing. # It is not intended for manual editing.
[[package]] [[package]]
name = "adler32" name = "adler32"
version = "1.0.4" version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
@ -75,9 +75,9 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.12.1" version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42" checksum = "e223af0dc48c96d4f8342ec01a4974f139df863896b316681efd36742f22cc67"
[[package]] [[package]]
name = "bincode" name = "bincode"
@ -104,7 +104,19 @@ dependencies = [
"block-padding", "block-padding",
"byte-tools", "byte-tools",
"byteorder", "byteorder",
"generic-array", "generic-array 0.12.3",
]
[[package]]
name = "block-buffer"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbcf92448676f82bb7a334c58bbce8b0d43580fb5362a9d608b18879d12a3d31"
dependencies = [
"block-padding",
"byte-tools",
"byteorder",
"generic-array 0.14.2",
] ]
[[package]] [[package]]
@ -366,7 +378,16 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
dependencies = [ dependencies = [
"generic-array", "generic-array 0.12.3",
]
[[package]]
name = "digest"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
dependencies = [
"generic-array 0.14.2",
] ]
[[package]] [[package]]
@ -377,9 +398,9 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]] [[package]]
name = "dtoa" name = "dtoa"
version = "0.4.5" version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3" checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
[[package]] [[package]]
name = "either" name = "either"
@ -611,6 +632,16 @@ dependencies = [
"typenum", "typenum",
] ]
[[package]]
name = "generic-array"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac746a5f3bbfdadd6106868134545e684693d54d9d44f6e9588a7d54af0bf980"
dependencies = [
"typenum",
"version_check",
]
[[package]] [[package]]
name = "getopts" name = "getopts"
version = "0.2.21" version = "0.2.21"
@ -912,9 +943,9 @@ dependencies = [
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "0.4.5" version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
[[package]] [[package]]
name = "jpeg-decoder" name = "jpeg-decoder"
@ -1462,7 +1493,7 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b336d94e8e4ce29bf15bba393164629764744c567e8ad306cc1fdd0119967fd" checksum = "7b336d94e8e4ce29bf15bba393164629764744c567e8ad306cc1fdd0119967fd"
dependencies = [ dependencies = [
"base64 0.12.1", "base64 0.12.2",
"chrono", "chrono",
"indexmap", "indexmap",
"line-wrap", "line-wrap",
@ -1615,10 +1646,11 @@ dependencies = [
[[package]] [[package]]
name = "rayon" name = "rayon"
version = "1.3.0" version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080"
dependencies = [ dependencies = [
"autocfg",
"crossbeam-deque", "crossbeam-deque",
"either", "either",
"rayon-core", "rayon-core",
@ -1626,9 +1658,9 @@ dependencies = [
[[package]] [[package]]
name = "rayon-core" name = "rayon-core"
version = "1.7.0" version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280"
dependencies = [ dependencies = [
"crossbeam-deque", "crossbeam-deque",
"crossbeam-queue", "crossbeam-queue",
@ -1718,7 +1750,7 @@ version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b82c9238b305f26f53443e3a4bc8528d64b8d0bee408ec949eb7bf5635ec680" checksum = "3b82c9238b305f26f53443e3a4bc8528d64b8d0bee408ec949eb7bf5635ec680"
dependencies = [ dependencies = [
"base64 0.12.1", "base64 0.12.2",
"bytes 0.5.4", "bytes 0.5.4",
"encoding_rs", "encoding_rs",
"futures-core", "futures-core",
@ -1749,9 +1781,9 @@ dependencies = [
[[package]] [[package]]
name = "ring" name = "ring"
version = "0.16.14" version = "0.16.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06b3fefa4f12272808f809a0af618501fdaba41a58963c5fb72238ab0be09603" checksum = "952cd6b98c85bbc30efa1ba5783b8abf12fec8b3287ffa52605b9432313e34e4"
dependencies = [ dependencies = [
"cc", "cc",
"libc", "libc",
@ -1917,20 +1949,20 @@ version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
dependencies = [ dependencies = [
"block-buffer", "block-buffer 0.7.3",
"digest", "digest 0.8.1",
"fake-simd", "fake-simd",
"opaque-debug", "opaque-debug",
] ]
[[package]] [[package]]
name = "sha2" name = "sha2"
version = "0.8.2" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" checksum = "72377440080fd008550fe9b441e854e43318db116f90181eef92e9ae9aedab48"
dependencies = [ dependencies = [
"block-buffer", "block-buffer 0.8.0",
"digest", "digest 0.9.0",
"fake-simd", "fake-simd",
"opaque-debug", "opaque-debug",
] ]
@ -1984,12 +2016,6 @@ dependencies = [
"deunicode", "deunicode",
] ]
[[package]]
name = "smallvec"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7cb5678e1615754284ec264d9bb5b4c27d2018577fd90ac0ceb578591ed5ee4"
[[package]] [[package]]
name = "socket2" name = "socket2"
version = "0.3.12" version = "0.3.12"
@ -2131,7 +2157,7 @@ dependencies = [
name = "templates" name = "templates"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"base64 0.12.1", "base64 0.12.2",
"config", "config",
"csv", "csv",
"errors", "errors",
@ -2232,6 +2258,12 @@ dependencies = [
"winapi 0.3.8", "winapi 0.3.8",
] ]
[[package]]
name = "tinyvec"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "0.2.21" version = "0.2.21"
@ -2391,11 +2423,11 @@ dependencies = [
[[package]] [[package]]
name = "unicode-normalization" name = "unicode-normalization"
version = "0.1.12" version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5479532badd04e128284890390c1e876ef7a993d0570b3597ae43dfa1d59afa4" checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977"
dependencies = [ dependencies = [
"smallvec", "tinyvec",
] ]
[[package]] [[package]]
@ -2698,9 +2730,9 @@ dependencies = [
[[package]] [[package]]
name = "xmlparser" name = "xmlparser"
version = "0.13.1" version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccb4240203dadf40be2de9369e5c6dec1bf427528115b030baca3334c18362d7" checksum = "52613e655f6f11f63c0fe7d1c3b5ef69e44d96df9b65dab296b441ed0e1125f5"
[[package]] [[package]]
name = "yaml-rust" name = "yaml-rust"

View file

@ -20,7 +20,7 @@ name = "zola"
[dependencies] [dependencies]
atty = "0.2.11" atty = "0.2.11"
clap = "2" clap = { version = "2", default-features = false }
chrono = "0.4" chrono = "0.4"
lazy_static = "1.1.0" lazy_static = "1.1.0"
termcolor = "1.0.4" termcolor = "1.0.4"

View file

@ -28,7 +28,7 @@ fn main() {
builder.add_plain_text_syntax(); builder.add_plain_text_syntax();
match builder.add_from_folder(package_dir, true) { match builder.add_from_folder(package_dir, true) {
Ok(_) => (), Ok(_) => (),
Err(e) => println!("Loading error: {:?}", e) Err(e) => println!("Loading error: {:?}", e),
}; };
let ss = builder.build(); let ss = builder.build();
dump_to_file(&ss, packpath_newlines).unwrap(); dump_to_file(&ss, packpath_newlines).unwrap();

View file

@ -4,7 +4,6 @@ use std::path::{Path, PathBuf};
use globset::{Glob, GlobSet, GlobSetBuilder}; use globset::{Glob, GlobSet, GlobSetBuilder};
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use syntect::parsing::{SyntaxSet, SyntaxSetBuilder}; use syntect::parsing::{SyntaxSet, SyntaxSetBuilder};
use toml;
use toml::Value as Toml; use toml::Value as Toml;
use crate::highlighting::THEME_SET; use crate::highlighting::THEME_SET;

View file

@ -3,7 +3,6 @@ use std::collections::HashMap;
use chrono::prelude::*; use chrono::prelude::*;
use serde_derive::Deserialize; use serde_derive::Deserialize;
use tera::{Map, Value}; use tera::{Map, Value};
use toml;
use errors::{bail, Result}; use errors::{bail, Result};
use utils::de::{fix_toml_dates, from_toml_datetime}; use utils::de::{fix_toml_dates, from_toml_datetime};
@ -57,15 +56,17 @@ pub struct PageFrontMatter {
pub extra: Map<String, Value>, pub extra: Map<String, Value>,
} }
/// Parse a TOML datetime from a string. /// Parse a string for a datetime coming from one of the supported TOML format
/// There are three alternatives: an offset datetime (plain RFC3339), a local datetime /// There are three alternatives:
/// (RFC3339 with timezone omitted) and a local date (YYYY-MM-DD). This tries each in /// 1. an offset datetime (plain RFC3339)
/// order. /// 2. a local datetime (RFC3339 with timezone omitted)
fn parse_datetime(d: &String) -> Option<NaiveDateTime> { /// 3. a local date (YYYY-MM-DD).
/// This tries each in order.
fn parse_datetime(d: &str) -> Option<NaiveDateTime> {
DateTime::parse_from_rfc3339(d) DateTime::parse_from_rfc3339(d)
.or(DateTime::parse_from_rfc3339(format!("{}Z", d).as_ref())) .or_else(|_| DateTime::parse_from_rfc3339(format!("{}Z", d).as_ref()))
.map(|s| s.naive_local()) .map(|s| s.naive_local())
.or(NaiveDate::parse_from_str(d, "%Y-%m-%d").map(|s| s.and_hms(0, 0, 0))) .or_else(|_| NaiveDate::parse_from_str(d, "%Y-%m-%d").map(|s| s.and_hms(0, 0, 0)))
.ok() .ok()
} }
@ -107,7 +108,7 @@ impl PageFrontMatter {
/// Converts the TOML datetime to a Chrono naive datetime /// Converts the TOML datetime to a Chrono naive datetime
/// Also grabs the year/month/day tuple that will be used in serialization /// Also grabs the year/month/day tuple that will be used in serialization
pub fn date_to_datetime(&mut self) { pub fn date_to_datetime(&mut self) {
self.datetime = self.date.as_ref().and_then(parse_datetime); self.datetime = self.date.as_ref().map(|s| s.as_ref()).and_then(parse_datetime);
self.datetime_tuple = self.datetime.map(|dt| (dt.year(), dt.month(), dt.day())); self.datetime_tuple = self.datetime.map(|dt| (dt.year(), dt.month(), dt.day()));
} }
@ -319,6 +320,23 @@ mod tests {
assert_eq!(res.unwrap().extra["something"]["some-date"], to_value("2002-14-01").unwrap()); assert_eq!(res.unwrap().extra["something"]["some-date"], to_value("2002-14-01").unwrap());
} }
#[test]
fn can_parse_fully_nested_dates_in_extra() {
let content = r#"
title = "Hello"
description = "hey there"
[extra]
date_example = 2020-05-04
[[extra.questions]]
date = 2020-05-03
name = "Who is the prime minister of Uganda?""#;
let res = PageFrontMatter::parse(content);
println!("{:?}", res);
assert!(res.is_ok());
assert_eq!(res.unwrap().extra["questions"][0]["date"], to_value("2020-05-03").unwrap());
}
#[test] #[test]
fn can_parse_taxonomies() { fn can_parse_taxonomies() {
let content = r#" let content = r#"

View file

@ -1,6 +1,5 @@
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use tera::{Map, Value}; use tera::{Map, Value};
use toml;
use super::{InsertAnchor, SortBy}; use super::{InsertAnchor, SortBy};
use errors::{bail, Result}; use errors::{bail, Result};

View file

@ -534,8 +534,11 @@ impl Site {
pub fn register_early_global_fns(&mut self) { pub fn register_early_global_fns(&mut self) {
self.tera.register_function( self.tera.register_function(
"get_url", "get_url",
global_fns::GetUrl::new(self.config.clone(), self.permalinks.clone(), global_fns::GetUrl::new(
vec![self.static_path.clone(), self.output_path.clone(), self.content_path.clone()]), self.config.clone(),
self.permalinks.clone(),
vec![self.static_path.clone(), self.output_path.clone(), self.content_path.clone()],
),
); );
self.tera.register_function( self.tera.register_function(
"resize_image", "resize_image",
@ -551,9 +554,14 @@ impl Site {
"get_taxonomy_url", "get_taxonomy_url",
global_fns::GetTaxonomyUrl::new(&self.config.default_language, &self.taxonomies), global_fns::GetTaxonomyUrl::new(&self.config.default_language, &self.taxonomies),
); );
self.tera.register_function("get_file_hash", global_fns::GetFileHash::new( self.tera.register_function(
vec![self.static_path.clone(), self.output_path.clone(), self.content_path.clone()] "get_file_hash",
)); global_fns::GetFileHash::new(vec![
self.static_path.clone(),
self.output_path.clone(),
self.content_path.clone(),
]),
);
} }
pub fn register_tera_global_fns(&mut self) { pub fn register_tera_global_fns(&mut self) {

View file

@ -696,8 +696,11 @@ fn can_cachebust_static_files() {
#[test] #[test]
fn can_get_hash_for_static_files() { fn can_get_hash_for_static_files() {
let (_, _tmp_dir, public) = build_site("test_site"); let (_, _tmp_dir, public) = build_site("test_site");
assert!(file_contains!(public, "index.html", assert!(file_contains!(
"src=\"https://replace-this-with-your-url.com/scripts/hello.js\"")); public,
"index.html",
"src=\"https://replace-this-with-your-url.com/scripts/hello.js\""
));
assert!(file_contains!(public, "index.html", assert!(file_contains!(public, "index.html",
"integrity=\"sha384-01422f31eaa721a6c4ac8c6fa09a27dd9259e0dfcf3c7593d7810d912a9de5ca2f582df978537bcd10f76896db61fbb9\"")); "integrity=\"sha384-01422f31eaa721a6c4ac8c6fa09a27dd9259e0dfcf3c7593d7810d912a9de5ca2f582df978537bcd10f76896db61fbb9\""));
} }

View file

@ -13,7 +13,7 @@ toml = "0.5"
csv = "1" csv = "1"
image = "0.23" image = "0.23"
serde_json = "1.0" serde_json = "1.0"
sha2 = "0.8" sha2 = "0.9"
url = "2" url = "2"
errors = { path = "../errors" } errors = { path = "../errors" }

View file

@ -19,6 +19,7 @@ pub fn markdown<S: BuildHasher>(
opts.insert(cmark::Options::ENABLE_TABLES); opts.insert(cmark::Options::ENABLE_TABLES);
opts.insert(cmark::Options::ENABLE_FOOTNOTES); opts.insert(cmark::Options::ENABLE_FOOTNOTES);
opts.insert(cmark::Options::ENABLE_STRIKETHROUGH); opts.insert(cmark::Options::ENABLE_STRIKETHROUGH);
opts.insert(cmark::Options::ENABLE_TASKLISTS);
let mut html = String::new(); let mut html = String::new();
let parser = cmark::Parser::new_ext(&s, opts); let parser = cmark::Parser::new_ext(&s, opts);

View file

@ -209,11 +209,9 @@ impl TeraFn for LoadData {
.header(header::ACCEPT, file_format.as_accept_header()) .header(header::ACCEPT, file_format.as_accept_header())
.send() .send()
.and_then(|res| res.error_for_status()) .and_then(|res| res.error_for_status())
.map_err(|e| { .map_err(|e| match e.status() {
match e.status() { Some(status) => format!("Failed to request {}: {}", url, status),
Some(status) => format!("Failed to request {}: {}", url, status), None => format!("Could not get response status for url: {}", url),
None => format!("Could not get response status for url: {}", url),
}
})?; })?;
response response
.text() .text()

View file

@ -1,21 +1,18 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::ffi::OsStr;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
use std::{fs, io, result}; use std::{fs, io, result};
use std::ffi::OsStr;
use sha2::{Digest, Sha256, Sha384, Sha512}; use sha2::{Digest, Sha256, Sha384, Sha512};
use tera::{from_value, to_value, Error, Function as TeraFn, Result, Value};
use svg_metadata as svg; use svg_metadata as svg;
use tera::{from_value, to_value, Error, Function as TeraFn, Result, Value};
use config::Config; use config::Config;
use image;
use image::GenericImageView; use image::GenericImageView;
use library::{Library, Taxonomy}; use library::{Library, Taxonomy};
use utils::site::resolve_internal_link; use utils::site::resolve_internal_link;
use imageproc;
#[macro_use] #[macro_use]
mod macros; mod macros;
@ -54,13 +51,17 @@ pub struct GetUrl {
search_paths: Vec<PathBuf>, search_paths: Vec<PathBuf>,
} }
impl GetUrl { impl GetUrl {
pub fn new(config: Config, permalinks: HashMap<String, String>, search_paths: Vec<PathBuf>) -> Self { pub fn new(
config: Config,
permalinks: HashMap<String, String>,
search_paths: Vec<PathBuf>,
) -> Self {
Self { config, permalinks, search_paths } Self { config, permalinks, search_paths }
} }
} }
fn make_path_with_lang(path: String, lang: &str, config: &Config) -> Result<String> { fn make_path_with_lang(path: String, lang: &str, config: &Config) -> Result<String> {
if lang == &config.default_language { if lang == config.default_language {
return Ok(path); return Ok(path);
} }
@ -70,18 +71,18 @@ fn make_path_with_lang(path: String, lang: &str, config: &Config) -> Result<Stri
); );
} }
let mut splitted_path: Vec<String> = path.split(".").map(String::from).collect(); let mut splitted_path: Vec<String> = path.split('.').map(String::from).collect();
let ilast = splitted_path.len() - 1; let ilast = splitted_path.len() - 1;
splitted_path[ilast] = format!("{}.{}", lang, splitted_path[ilast]); splitted_path[ilast] = format!("{}.{}", lang, splitted_path[ilast]);
Ok(splitted_path.join(".")) Ok(splitted_path.join("."))
} }
fn open_file(search_paths: &Vec<PathBuf>, url: &String) -> result::Result<fs::File, io::Error> { fn open_file(search_paths: &[PathBuf], url: &str) -> result::Result<fs::File, io::Error> {
let cleaned_url = url.trim_start_matches("@/").trim_start_matches("/"); let cleaned_url = url.trim_start_matches("@/").trim_start_matches('/');
for base_path in search_paths { for base_path in search_paths {
match fs::File::open(base_path.join(cleaned_url)) { match fs::File::open(base_path.join(cleaned_url)) {
Ok(f) => return Ok(f), Ok(f) => return Ok(f),
Err(_) => continue Err(_) => continue,
}; };
} }
Err(io::Error::from(io::ErrorKind::NotFound)) Err(io::Error::from(io::ErrorKind::NotFound))
@ -90,23 +91,28 @@ fn open_file(search_paths: &Vec<PathBuf>, url: &String) -> result::Result<fs::Fi
fn compute_file_sha256(mut file: fs::File) -> result::Result<String, io::Error> { fn compute_file_sha256(mut file: fs::File) -> result::Result<String, io::Error> {
let mut hasher = Sha256::new(); let mut hasher = Sha256::new();
io::copy(&mut file, &mut hasher)?; io::copy(&mut file, &mut hasher)?;
Ok(format!("{:x}", hasher.result())) Ok(format!("{:x}", hasher.finalize()))
} }
fn compute_file_sha384(mut file: fs::File) -> result::Result<String, io::Error> { fn compute_file_sha384(mut file: fs::File) -> result::Result<String, io::Error> {
let mut hasher = Sha384::new(); let mut hasher = Sha384::new();
io::copy(&mut file, &mut hasher)?; io::copy(&mut file, &mut hasher)?;
Ok(format!("{:x}", hasher.result())) Ok(format!("{:x}", hasher.finalize()))
} }
fn compute_file_sha512(mut file: fs::File) -> result::Result<String, io::Error> { fn compute_file_sha512(mut file: fs::File) -> result::Result<String, io::Error> {
let mut hasher = Sha512::new(); let mut hasher = Sha512::new();
io::copy(&mut file, &mut hasher)?; io::copy(&mut file, &mut hasher)?;
Ok(format!("{:x}", hasher.result())) Ok(format!("{:x}", hasher.finalize()))
} }
fn file_not_found_err(search_paths: &Vec<PathBuf>, url: &String) -> Result<Value> { fn file_not_found_err(search_paths: &[PathBuf], url: &str) -> Result<Value> {
Err(format!("file `{}` not found; searched in{}", url, Err(format!(
search_paths.iter().fold(String::new(), "file `{}` not found; searched in{}",
|acc, arg| acc + " " + arg.to_str().unwrap())).into()) url,
search_paths.iter().fold(String::new(), |acc, arg| acc + " " + arg.to_str().unwrap())
)
.into())
} }
impl TeraFn for GetUrl { impl TeraFn for GetUrl {
@ -151,8 +157,8 @@ impl TeraFn for GetUrl {
match open_file(&self.search_paths, &path).and_then(compute_file_sha256) { match open_file(&self.search_paths, &path).and_then(compute_file_sha256) {
Ok(hash) => { Ok(hash) => {
permalink = format!("{}?h={}", permalink, hash); permalink = format!("{}?h={}", permalink, hash);
}, }
Err(_) => return file_not_found_err(&self.search_paths, &path) Err(_) => return file_not_found_err(&self.search_paths, &path),
}; };
} }
Ok(to_value(permalink).unwrap()) Ok(to_value(permalink).unwrap())
@ -183,20 +189,21 @@ impl TeraFn for GetFileHash {
u16, u16,
args.get("sha_type"), args.get("sha_type"),
"`get_file_hash`: `sha_type` must be 256, 384 or 512" "`get_file_hash`: `sha_type` must be 256, 384 or 512"
).unwrap_or(DEFAULT_SHA_TYPE); )
.unwrap_or(DEFAULT_SHA_TYPE);
let compute_hash_fn = match sha_type { let compute_hash_fn = match sha_type {
256 => compute_file_sha256, 256 => compute_file_sha256,
384 => compute_file_sha384, 384 => compute_file_sha384,
512 => compute_file_sha512, 512 => compute_file_sha512,
_ => return Err("`get_file_hash`: `sha_type` must be 256, 384 or 512".into()) _ => return Err("`get_file_hash`: `sha_type` must be 256, 384 or 512".into()),
}; };
let hash = open_file(&self.search_paths, &path).and_then(compute_hash_fn); let hash = open_file(&self.search_paths, &path).and_then(compute_hash_fn);
match hash { match hash {
Ok(digest) => Ok(to_value(digest).unwrap()), Ok(digest) => Ok(to_value(digest).unwrap()),
Err(_) => file_not_found_err(&self.search_paths, &path) Err(_) => file_not_found_err(&self.search_paths, &path),
} }
} }
} }
@ -297,7 +304,7 @@ fn image_dimensions(path: &PathBuf) -> Result<(u32, u32)> {
match (img.height(), img.width(), img.view_box()) { match (img.height(), img.width(), img.view_box()) {
(Some(h), Some(w), _) => Ok((h as u32, w as u32)), (Some(h), Some(w), _) => Ok((h as u32, w as u32)),
(_, _, Some(view_box)) => Ok((view_box.height as u32, view_box.width as u32)), (_, _, Some(view_box)) => Ok((view_box.height as u32, view_box.width as u32)),
_ => Err("Invalid dimensions: SVG width/height and viewbox not set.".into()) _ => Err("Invalid dimensions: SVG width/height and viewbox not set.".into()),
} }
} else { } else {
let img = image::open(&path) let img = image::open(&path)
@ -465,7 +472,7 @@ impl TeraFn for GetTaxonomy {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{GetTaxonomy, GetTaxonomyUrl, GetUrl, Trans, GetFileHash}; use super::{GetFileHash, GetTaxonomy, GetTaxonomyUrl, GetUrl, Trans};
use std::collections::HashMap; use std::collections::HashMap;
use std::env::temp_dir; use std::env::temp_dir;
@ -786,7 +793,10 @@ title = "A title"
let mut args = HashMap::new(); let mut args = HashMap::new();
args.insert("path".to_string(), to_value("app.css").unwrap()); args.insert("path".to_string(), to_value("app.css").unwrap());
args.insert("sha_type".to_string(), to_value(256).unwrap()); args.insert("sha_type".to_string(), to_value(256).unwrap());
assert_eq!(static_fn.call(&args).unwrap(), "572e691dc68c3fcd653ae463261bdb38f35dc6f01715d9ce68799319dd158840"); assert_eq!(
static_fn.call(&args).unwrap(),
"572e691dc68c3fcd653ae463261bdb38f35dc6f01715d9ce68799319dd158840"
);
} }
#[test] #[test]
@ -812,8 +822,10 @@ title = "A title"
let mut args = HashMap::new(); let mut args = HashMap::new();
args.insert("path".to_string(), to_value("doesnt-exist").unwrap()); args.insert("path".to_string(), to_value("doesnt-exist").unwrap());
assert_eq!( assert_eq!(
format!("file `doesnt-exist` not found; searched in {}", format!(
TEST_CONTEXT.static_path.to_str().unwrap()), "file `doesnt-exist` not found; searched in {}",
TEST_CONTEXT.static_path.to_str().unwrap()
),
format!("{}", static_fn.call(&args).unwrap_err()) format!("{}", static_fn.call(&args).unwrap_err())
); );
} }

View file

@ -1,6 +1,5 @@
use serde::{Deserialize, Deserializer}; use serde::{Deserialize, Deserializer};
use tera::{Map, Value}; use tera::{Map, Value};
use toml;
/// Used as an attribute when we want to convert from TOML to a string date /// Used as an attribute when we want to convert from TOML to a string date
pub fn from_toml_datetime<'de, D>(deserializer: D) -> Result<Option<String>, D::Error> pub fn from_toml_datetime<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
@ -43,6 +42,16 @@ pub fn fix_toml_dates(table: Map<String, Value>) -> Value {
Value::Object(o) => { Value::Object(o) => {
new.insert(key, convert_toml_date(o)); new.insert(key, convert_toml_date(o));
} }
Value::Array(arr) => {
let mut new_arr = Vec::with_capacity(arr.len());
for v in arr {
match v {
Value::Object(o) => new_arr.push(fix_toml_dates(o)),
_ => new_arr.push(v),
};
}
new.insert(key, Value::Array(new_arr));
}
_ => { _ => {
new.insert(key, value); new.insert(key, value);
} }

View file

@ -4,7 +4,7 @@
command = "zola build" command = "zola build"
[build.environment] [build.environment]
ZOLA_VERSION = "0.8.0" ZOLA_VERSION = "0.11.0"
[context.deploy-preview] [context.deploy-preview]
command = "zola build --base-url $DEPLOY_PRIME_URL" command = "zola build --base-url $DEPLOY_PRIME_URL"

View file

@ -35,7 +35,6 @@ use hyper_staticfile::ResolveResult;
use tokio::io::AsyncReadExt; use tokio::io::AsyncReadExt;
use chrono::prelude::*; use chrono::prelude::*;
use ctrlc;
use notify::{watcher, RecursiveMode, Watcher}; use notify::{watcher, RecursiveMode, Watcher};
use ws::{Message, Sender, WebSocket}; use ws::{Message, Sender, WebSocket};
@ -45,8 +44,6 @@ use site::Site;
use utils::fs::copy_file; use utils::fs::copy_file;
use crate::console; use crate::console;
use open;
use rebuild;
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
enum ChangeKind { enum ChangeKind {

View file

@ -5,7 +5,6 @@ use std::error::Error as StdError;
use std::io::Write; use std::io::Write;
use std::time::Instant; use std::time::Instant;
use atty;
use chrono::Duration; use chrono::Duration;
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};