Browse Source

fmt/clippy

index-subcmd
Vincent Prouillet 5 years ago
parent
commit
a12e9512bc
15 changed files with 114 additions and 81 deletions
  1. +1
    -1
      README.md
  2. +1
    -1
      components/config/src/lib.rs
  3. +24
    -18
      components/library/src/content/file_info.rs
  4. +7
    -3
      components/library/src/content/page.rs
  5. +5
    -1
      components/library/src/content/section.rs
  6. +5
    -7
      components/library/src/library.rs
  7. +1
    -1
      components/rebuild/src/lib.rs
  8. +1
    -5
      components/rebuild/tests/rebuild.rs
  9. +19
    -8
      components/site/src/lib.rs
  10. +5
    -2
      components/site/tests/common.rs
  11. +9
    -4
      components/site/tests/site.rs
  12. +13
    -5
      components/site/tests/site_i18n.rs
  13. +15
    -16
      components/templates/src/global_fns/load_data.rs
  14. +5
    -3
      components/templates/src/global_fns/mod.rs
  15. +3
    -6
      src/cmd/serve.rs

+ 1
- 1
README.md View File

@@ -16,7 +16,7 @@ in the `docs/content` folder of the repository and the community can use [its fo
| Syntax highlighting | ✔ | ✔ | ✔ | ✔ | | Syntax highlighting | ✔ | ✔ | ✔ | ✔ |
| Sass compilation | ✔ | ✔ | ✔ | ✔ | | Sass compilation | ✔ | ✔ | ✔ | ✔ |
| Assets co-location | ✔ | ✔ | ✔ | ✔ | | Assets co-location | ✔ | ✔ | ✔ | ✔ |
| i18n | ✕ | ✕ | ✔ | ✔ |
| Multilingual site | ✔ | ✕ | ✔ | ✔ |
| Image processing | ✔ | ✕ | ✔ | ✔ | | Image processing | ✔ | ✕ | ✔ | ✔ |
| Sane & powerful template engine | ✔ | ~ | ~ | ✔ | | Sane & powerful template engine | ✔ | ~ | ~ | ✔ |
| Themes | ✔ | ✕ | ✔ | ✔ | | Themes | ✔ | ✕ | ✔ | ✔ |


+ 1
- 1
components/config/src/lib.rs View File

@@ -12,7 +12,7 @@ extern crate syntect;
mod config; mod config;
pub mod highlighting; pub mod highlighting;
mod theme; mod theme;
pub use config::{Config, Taxonomy, Language};
pub use config::{Config, Language, Taxonomy};


use std::path::Path; use std::path::Path;




+ 24
- 18
components/library/src/content/file_info.rs View File

@@ -119,7 +119,7 @@ impl FileInfo {


// Go with the assumption that no one is using `.` in filenames when using i18n // Go with the assumption that no one is using `.` in filenames when using i18n
// We can document that // We can document that
let mut parts: Vec<String> = self.name.splitn(2,'.').map(|s| s.to_string()).collect();
let mut parts: Vec<String> = self.name.splitn(2, '.').map(|s| s.to_string()).collect();


// The language code is not present in the config: typo or the user forgot to add it to the // The language code is not present in the config: typo or the user forgot to add it to the
// config // config
@@ -155,7 +155,7 @@ mod tests {


use config::{Config, Language}; use config::{Config, Language};


use super::{FileInfo, find_content_components};
use super::{find_content_components, FileInfo};


#[test] #[test]
fn can_find_content_components() { fn can_find_content_components() {
@@ -165,17 +165,19 @@ mod tests {
} }
#[test] #[test]
fn can_find_components_in_page_with_assets() { fn can_find_components_in_page_with_assets() {
let file =
FileInfo::new_page(&Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.md"));
let file = FileInfo::new_page(&Path::new(
"/home/vincent/code/site/content/posts/tutorials/python/index.md",
));
assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]); assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]);
} }


#[test] #[test]
fn can_find_valid_language_in_page() { fn can_find_valid_language_in_page() {
let mut config = Config::default(); let mut config = Config::default();
config.languages.push(Language {code: String::from("fr"), rss: false});
let mut file =
FileInfo::new_page(&Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"));
config.languages.push(Language { code: String::from("fr"), rss: false });
let mut file = FileInfo::new_page(&Path::new(
"/home/vincent/code/site/content/posts/tutorials/python.fr.md",
));
let res = file.find_language(&config); let res = file.find_language(&config);
assert!(res.is_ok()); assert!(res.is_ok());
assert_eq!(res.unwrap(), Some(String::from("fr"))); assert_eq!(res.unwrap(), Some(String::from("fr")));
@@ -184,9 +186,10 @@ mod tests {
#[test] #[test]
fn can_find_valid_language_in_page_with_assets() { fn can_find_valid_language_in_page_with_assets() {
let mut config = Config::default(); let mut config = Config::default();
config.languages.push(Language {code: String::from("fr"), rss: false});
let mut file =
FileInfo::new_page(&Path::new("/home/vincent/code/site/content/posts/tutorials/python/index.fr.md"));
config.languages.push(Language { code: String::from("fr"), rss: false });
let mut file = FileInfo::new_page(&Path::new(
"/home/vincent/code/site/content/posts/tutorials/python/index.fr.md",
));
assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]); assert_eq!(file.components, ["posts".to_string(), "tutorials".to_string()]);
let res = file.find_language(&config); let res = file.find_language(&config);
assert!(res.is_ok()); assert!(res.is_ok());
@@ -196,8 +199,9 @@ mod tests {
#[test] #[test]
fn do_nothing_on_unknown_language_in_page_with_i18n_off() { fn do_nothing_on_unknown_language_in_page_with_i18n_off() {
let config = Config::default(); let config = Config::default();
let mut file =
FileInfo::new_page(&Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"));
let mut file = FileInfo::new_page(&Path::new(
"/home/vincent/code/site/content/posts/tutorials/python.fr.md",
));
let res = file.find_language(&config); let res = file.find_language(&config);
assert!(res.is_ok()); assert!(res.is_ok());
assert!(res.unwrap().is_none()); assert!(res.unwrap().is_none());
@@ -206,9 +210,10 @@ mod tests {
#[test] #[test]
fn errors_on_unknown_language_in_page_with_i18n_on() { fn errors_on_unknown_language_in_page_with_i18n_on() {
let mut config = Config::default(); let mut config = Config::default();
config.languages.push(Language {code: String::from("it"), rss: false});
let mut file =
FileInfo::new_page(&Path::new("/home/vincent/code/site/content/posts/tutorials/python.fr.md"));
config.languages.push(Language { code: String::from("it"), rss: false });
let mut file = FileInfo::new_page(&Path::new(
"/home/vincent/code/site/content/posts/tutorials/python.fr.md",
));
let res = file.find_language(&config); let res = file.find_language(&config);
assert!(res.is_err()); assert!(res.is_err());
} }
@@ -216,9 +221,10 @@ mod tests {
#[test] #[test]
fn can_find_valid_language_in_section() { fn can_find_valid_language_in_section() {
let mut config = Config::default(); let mut config = Config::default();
config.languages.push(Language {code: String::from("fr"), rss: false});
let mut file =
FileInfo::new_section(&Path::new("/home/vincent/code/site/content/posts/tutorials/_index.fr.md"));
config.languages.push(Language { code: String::from("fr"), rss: false });
let mut file = FileInfo::new_section(&Path::new(
"/home/vincent/code/site/content/posts/tutorials/_index.fr.md",
));
let res = file.find_language(&config); let res = file.find_language(&config);
assert!(res.is_ok()); assert!(res.is_ok());
assert_eq!(res.unwrap(), Some(String::from("fr"))); assert_eq!(res.unwrap(), Some(String::from("fr")));


+ 7
- 3
components/library/src/content/page.rs View File

@@ -74,6 +74,8 @@ pub struct Page {
/// The language of that page. `None` if the user doesn't setup `languages` in config. /// The language of that page. `None` if the user doesn't setup `languages` in config.
/// Corresponds to the lang in the {slug}.{lang}.md file scheme /// Corresponds to the lang in the {slug}.{lang}.md file scheme
pub lang: Option<String>, pub lang: Option<String>,
/// Contains all the translated version of that page
pub translations: Vec<Key>,
} }


impl Page { impl Page {
@@ -101,6 +103,7 @@ impl Page {
word_count: None, word_count: None,
reading_time: None, reading_time: None,
lang: None, lang: None,
translations: Vec::new(),
} }
} }


@@ -300,6 +303,7 @@ impl Default for Page {
word_count: None, word_count: None,
reading_time: None, reading_time: None,
lang: None, lang: None,
translations: Vec::new(),
} }
} }
} }
@@ -577,7 +581,7 @@ Hello world
#[test] #[test]
fn can_specify_language_in_filename() { fn can_specify_language_in_filename() {
let mut config = Config::default(); let mut config = Config::default();
config.languages.push(Language {code: String::from("fr"), rss: false});
config.languages.push(Language { code: String::from("fr"), rss: false });
let content = r#" let content = r#"
+++ +++
+++ +++
@@ -594,7 +598,7 @@ Bonjour le monde"#
#[test] #[test]
fn can_specify_language_in_filename_with_date() { fn can_specify_language_in_filename_with_date() {
let mut config = Config::default(); let mut config = Config::default();
config.languages.push(Language {code: String::from("fr"), rss: false});
config.languages.push(Language { code: String::from("fr"), rss: false });
let content = r#" let content = r#"
+++ +++
+++ +++
@@ -612,7 +616,7 @@ Bonjour le monde"#
#[test] #[test]
fn i18n_frontmatter_path_overrides_default_permalink() { fn i18n_frontmatter_path_overrides_default_permalink() {
let mut config = Config::default(); let mut config = Config::default();
config.languages.push(Language {code: String::from("fr"), rss: false});
config.languages.push(Language { code: String::from("fr"), rss: false });
let content = r#" let content = r#"
+++ +++
path = "bonjour" path = "bonjour"


+ 5
- 1
components/library/src/content/section.rs View File

@@ -54,6 +54,8 @@ pub struct Section {
/// The language of that section. `None` if the user doesn't setup `languages` in config. /// The language of that section. `None` if the user doesn't setup `languages` in config.
/// Corresponds to the lang in the _index.{lang}.md file scheme /// Corresponds to the lang in the _index.{lang}.md file scheme
pub lang: Option<String>, pub lang: Option<String>,
/// Contains all the translated version of that section
pub translations: Vec<Key>,
} }


impl Section { impl Section {
@@ -78,6 +80,7 @@ impl Section {
word_count: None, word_count: None,
reading_time: None, reading_time: None,
lang: None, lang: None,
translations: Vec::new(),
} }
} }


@@ -235,6 +238,7 @@ impl Default for Section {
reading_time: None, reading_time: None,
word_count: None, word_count: None,
lang: None, lang: None,
translations: Vec::new(),
} }
} }
} }
@@ -302,7 +306,7 @@ mod tests {
#[test] #[test]
fn can_specify_language_in_filename() { fn can_specify_language_in_filename() {
let mut config = Config::default(); let mut config = Config::default();
config.languages.push(Language {code: String::from("fr"), rss: false});
config.languages.push(Language { code: String::from("fr"), rss: false });
let content = r#" let content = r#"
+++ +++
+++ +++


+ 5
- 7
components/library/src/library.rs View File

@@ -80,12 +80,8 @@ impl Library {
/// Find out the direct subsections of each subsection if there are some /// Find out the direct subsections of each subsection if there are some
/// as well as the pages for each section /// as well as the pages for each section
pub fn populate_sections(&mut self) { pub fn populate_sections(&mut self) {
let root_path= self
.sections
.values()
.find(|s| s.is_index())
.map(|s| s.file.parent.clone())
.unwrap();
let root_path =
self.sections.values().find(|s| s.is_index()).map(|s| s.file.parent.clone()).unwrap();
// We are going to get both the ancestors and grandparents for each section in one go // We are going to get both the ancestors and grandparents for each section in one go
let mut ancestors: HashMap<PathBuf, Vec<_>> = HashMap::new(); let mut ancestors: HashMap<PathBuf, Vec<_>> = HashMap::new();
let mut subsections: HashMap<PathBuf, Vec<_>> = HashMap::new(); let mut subsections: HashMap<PathBuf, Vec<_>> = HashMap::new();
@@ -119,7 +115,9 @@ impl Library {
if path == section.file.parent { if path == section.file.parent {
continue; continue;
} }
if let Some(section_key) = self.paths_to_sections.get(&path.join(&section.file.filename)) {
if let Some(section_key) =
self.paths_to_sections.get(&path.join(&section.file.filename))
{
parents.push(*section_key); parents.push(*section_key);
} }
} }


+ 1
- 1
components/rebuild/src/lib.rs View File

@@ -288,7 +288,7 @@ pub fn after_content_rename(site: &mut Site, old: &Path, new: &Path) -> Result<(
old.to_path_buf() old.to_path_buf()
}; };
site.library.remove_page(&old_path); site.library.remove_page(&old_path);
return handle_page_editing(site, &new_path);
handle_page_editing(site, &new_path)
} }


/// What happens when a section or a page is created/edited /// What happens when a section or a page is created/edited


+ 1
- 5
components/rebuild/tests/rebuild.rs View File

@@ -267,9 +267,5 @@ Edite
let res = after_content_change(&mut site, &file_path); let res = after_content_change(&mut site, &file_path);
println!("{:?}", res); println!("{:?}", res);
assert!(res.is_ok()); assert!(res.is_ok());
assert!(file_contains!(
site_path,
"public/fr/blog/with-assets/index.html",
"Edite"
));
assert!(file_contains!(site_path, "public/fr/blog/with-assets/index.html", "Edite"));
} }

+ 19
- 8
components/site/src/lib.rs View File

@@ -152,7 +152,10 @@ impl Site {
fn index_section_paths(&self) -> Vec<(PathBuf, Option<String>)> { fn index_section_paths(&self) -> Vec<(PathBuf, Option<String>)> {
let mut res = vec![(self.content_path.join("_index.md"), None)]; let mut res = vec![(self.content_path.join("_index.md"), None)];
for language in &self.config.languages { for language in &self.config.languages {
res.push((self.content_path.join(format!("_index.{}.md", language.code)), Some(language.code.clone())));
res.push((
self.content_path.join(format!("_index.{}.md", language.code)),
Some(language.code.clone()),
));
} }
res res
} }
@@ -189,7 +192,9 @@ impl Site {
.unwrap() .unwrap()
.filter_map(|e| e.ok()) .filter_map(|e| e.ok())
.filter(|e| !e.as_path().file_name().unwrap().to_str().unwrap().starts_with('.')) .filter(|e| !e.as_path().file_name().unwrap().to_str().unwrap().starts_with('.'))
.partition(|entry| entry.as_path().file_name().unwrap().to_str().unwrap().starts_with("_index."));
.partition(|entry| {
entry.as_path().file_name().unwrap().to_str().unwrap().starts_with("_index.")
});


self.library = Library::new(page_entries.len(), section_entries.len()); self.library = Library::new(page_entries.len(), section_entries.len());


@@ -241,7 +246,8 @@ impl Site {
let mut index_section = Section::default(); let mut index_section = Section::default();
index_section.file.parent = self.content_path.clone(); index_section.file.parent = self.content_path.clone();
index_section.file.name = "_index".to_string(); index_section.file.name = "_index".to_string();
index_section.file.filename = index_path.file_name().unwrap().to_string_lossy().to_string();
index_section.file.filename =
index_path.file_name().unwrap().to_string_lossy().to_string();
if let Some(ref l) = lang { if let Some(ref l) = lang {
index_section.permalink = self.config.make_permalink(l); index_section.permalink = self.config.make_permalink(l);
let filename = format!("_index.{}.md", l); let filename = format!("_index.{}.md", l);
@@ -353,7 +359,8 @@ impl Site {
pub fn add_page(&mut self, mut page: Page, render: bool) -> Result<Option<Page>> { pub fn add_page(&mut self, mut page: Page, render: bool) -> Result<Option<Page>> {
self.permalinks.insert(page.file.relative.clone(), page.permalink.clone()); self.permalinks.insert(page.file.relative.clone(), page.permalink.clone());
if render { if render {
let insert_anchor = self.find_parent_section_insert_anchor(&page.file.parent, &page.lang);
let insert_anchor =
self.find_parent_section_insert_anchor(&page.file.parent, &page.lang);
page.render_markdown(&self.permalinks, &self.tera, &self.config, insert_anchor)?; page.render_markdown(&self.permalinks, &self.tera, &self.config, insert_anchor)?;
} }
let prev = self.library.remove_page(&page.file.path); let prev = self.library.remove_page(&page.file.path);
@@ -379,7 +386,11 @@ impl Site {


/// Finds the insert_anchor for the parent section of the directory at `path`. /// Finds the insert_anchor for the parent section of the directory at `path`.
/// Defaults to `AnchorInsert::None` if no parent section found /// Defaults to `AnchorInsert::None` if no parent section found
pub fn find_parent_section_insert_anchor(&self, parent_path: &PathBuf, lang: &Option<String>) -> InsertAnchor {
pub fn find_parent_section_insert_anchor(
&self,
parent_path: &PathBuf,
lang: &Option<String>,
) -> InsertAnchor {
let parent = if let Some(ref l) = lang { let parent = if let Some(ref l) = lang {
parent_path.join(format!("_index.{}.md", l)) parent_path.join(format!("_index.{}.md", l))
} else { } else {
@@ -746,7 +757,7 @@ impl Site {
let number_pagers = (section.pages.len() as f64 let number_pagers = (section.pages.len() as f64
/ section.meta.paginate_by.unwrap() as f64) / section.meta.paginate_by.unwrap() as f64)
.ceil() as isize; .ceil() as isize;
for i in 1..number_pagers + 1 {
for i in 1..=number_pagers {
let permalink = let permalink =
format!("{}{}/{}/", section.permalink, section.meta.paginate_path, i); format!("{}{}/{}/", section.permalink, section.meta.paginate_path, i);
sections.push(SitemapEntry::new(permalink, None)) sections.push(SitemapEntry::new(permalink, None))
@@ -770,7 +781,7 @@ impl Site {
let number_pagers = (item.pages.len() as f64 let number_pagers = (item.pages.len() as f64
/ taxonomy.kind.paginate_by.unwrap() as f64) / taxonomy.kind.paginate_by.unwrap() as f64)
.ceil() as isize; .ceil() as isize;
for i in 1..number_pagers + 1 {
for i in 1..=number_pagers {
let permalink = self.config.make_permalink(&format!( let permalink = self.config.make_permalink(&format!(
"{}/{}/{}/{}", "{}/{}/{}/{}",
name, name,
@@ -822,7 +833,7 @@ impl Site {


context.insert("last_build_date", &pages[0].meta.date.clone()); context.insert("last_build_date", &pages[0].meta.date.clone());
// limit to the last n elements if the limit is set; otherwise use all. // limit to the last n elements if the limit is set; otherwise use all.
let num_entries = self.config.rss_limit.unwrap_or(pages.len());
let num_entries = self.config.rss_limit.unwrap_or_else(|| pages.len());
let p = pages let p = pages
.iter() .iter()
.take(num_entries) .take(num_entries)


+ 5
- 2
components/site/tests/common.rs View File

@@ -1,5 +1,5 @@
extern crate tempfile;
extern crate site; extern crate site;
extern crate tempfile;


use std::env; use std::env;
use std::path::PathBuf; use std::path::PathBuf;
@@ -50,7 +50,10 @@ pub fn build_site(name: &str) -> (Site, TempDir, PathBuf) {
} }


/// Same as `build_site` but has a hook to setup some config options /// Same as `build_site` but has a hook to setup some config options
pub fn build_site_with_setup<F>(name: &str, mut setup_cb: F) -> (Site, TempDir, PathBuf) where F: FnMut(Site) -> (Site, bool) {
pub fn build_site_with_setup<F>(name: &str, mut setup_cb: F) -> (Site, TempDir, PathBuf)
where
F: FnMut(Site) -> (Site, bool),
{
let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf(); let mut path = env::current_dir().unwrap().parent().unwrap().parent().unwrap().to_path_buf();
path.push(name); path.push(name);
let site = Site::new(&path, "config.toml").unwrap(); let site = Site::new(&path, "config.toml").unwrap();


+ 9
- 4
components/site/tests/site.rs View File

@@ -6,9 +6,9 @@ use std::collections::HashMap;
use std::env; use std::env;
use std::path::Path; use std::path::Path;


use common::{build_site, build_site_with_setup};
use config::Taxonomy; use config::Taxonomy;
use site::Site; use site::Site;
use common::{build_site, build_site_with_setup};


#[test] #[test]
fn can_parse_site() { fn can_parse_site() {
@@ -425,7 +425,10 @@ fn can_build_site_with_pagination_for_index() {
let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| { let (_, _tmp_dir, public) = build_site_with_setup("test_site", |mut site| {
site.load().unwrap(); site.load().unwrap();
{ {
let index = site.library.get_section_mut(&site.base_path.join("content").join("_index.md")).unwrap();
let index = site
.library
.get_section_mut(&site.base_path.join("content").join("_index.md"))
.unwrap();
index.meta.paginate_by = Some(2); index.meta.paginate_by = Some(2);
index.meta.template = Some("index_paginated.html".to_string()); index.meta.template = Some("index_paginated.html".to_string());
} }
@@ -482,8 +485,10 @@ fn can_build_site_with_pagination_for_taxonomy() {
for (i, (_, page)) in site.library.pages_mut().iter_mut().enumerate() { for (i, (_, page)) in site.library.pages_mut().iter_mut().enumerate() {
page.meta.taxonomies = { page.meta.taxonomies = {
let mut taxonomies = HashMap::new(); let mut taxonomies = HashMap::new();
taxonomies
.insert("tags".to_string(), vec![if i % 2 == 0 { "A" } else { "B" }.to_string()]);
taxonomies.insert(
"tags".to_string(),
vec![if i % 2 == 0 { "A" } else { "B" }.to_string()],
);
taxonomies taxonomies
}; };
} }


+ 13
- 5
components/site/tests/site_i18n.rs View File

@@ -3,8 +3,8 @@ mod common;


use std::env; use std::env;


use site::Site;
use common::build_site; use common::build_site;
use site::Site;


#[test] #[test]
fn can_parse_multilingual_site() { fn can_parse_multilingual_site() {
@@ -17,11 +17,13 @@ fn can_parse_multilingual_site() {
assert_eq!(site.library.sections().len(), 4); assert_eq!(site.library.sections().len(), 4);


// default index sections // default index sections
let default_index_section = site.library.get_section(&path.join("content").join("_index.md")).unwrap();
let default_index_section =
site.library.get_section(&path.join("content").join("_index.md")).unwrap();
assert_eq!(default_index_section.pages.len(), 1); assert_eq!(default_index_section.pages.len(), 1);
assert!(default_index_section.ancestors.is_empty()); assert!(default_index_section.ancestors.is_empty());


let fr_index_section = site.library.get_section(&path.join("content").join("_index.fr.md")).unwrap();
let fr_index_section =
site.library.get_section(&path.join("content").join("_index.fr.md")).unwrap();
assert_eq!(fr_index_section.pages.len(), 1); assert_eq!(fr_index_section.pages.len(), 1);
assert!(fr_index_section.ancestors.is_empty()); assert!(fr_index_section.ancestors.is_empty());


@@ -31,7 +33,10 @@ fn can_parse_multilingual_site() {
let default_blog = site.library.get_section(&blog_path.join("_index.md")).unwrap(); let default_blog = site.library.get_section(&blog_path.join("_index.md")).unwrap();
assert_eq!(default_blog.subsections.len(), 0); assert_eq!(default_blog.subsections.len(), 0);
assert_eq!(default_blog.pages.len(), 4); assert_eq!(default_blog.pages.len(), 4);
assert_eq!(default_blog.ancestors, vec![*site.library.get_section_key(&default_index_section.file.path).unwrap()]);
assert_eq!(
default_blog.ancestors,
vec![*site.library.get_section_key(&default_index_section.file.path).unwrap()]
);
for key in &default_blog.pages { for key in &default_blog.pages {
let page = site.library.get_page_by_key(*key); let page = site.library.get_page_by_key(*key);
assert_eq!(page.lang, None); assert_eq!(page.lang, None);
@@ -40,7 +45,10 @@ fn can_parse_multilingual_site() {
let fr_blog = site.library.get_section(&blog_path.join("_index.fr.md")).unwrap(); let fr_blog = site.library.get_section(&blog_path.join("_index.fr.md")).unwrap();
assert_eq!(fr_blog.subsections.len(), 0); assert_eq!(fr_blog.subsections.len(), 0);
assert_eq!(fr_blog.pages.len(), 3); assert_eq!(fr_blog.pages.len(), 3);
assert_eq!(fr_blog.ancestors, vec![*site.library.get_section_key(&fr_index_section.file.path).unwrap()]);
assert_eq!(
fr_blog.ancestors,
vec![*site.library.get_section_key(&fr_index_section.file.path).unwrap()]
);
for key in &fr_blog.pages { for key in &fr_blog.pages {
let page = site.library.get_page_by_key(*key); let page = site.library.get_page_by_key(*key);
assert_eq!(page.lang, Some("fr".to_string())); assert_eq!(page.lang, Some("fr".to_string()));


+ 15
- 16
components/templates/src/global_fns/load_data.rs View File

@@ -50,24 +50,24 @@ impl FromStr for OutputFormat {
type Err = Error; type Err = Error;


fn from_str(output_format: &str) -> Result<Self> { fn from_str(output_format: &str) -> Result<Self> {
return match output_format {
match output_format {
"toml" => Ok(OutputFormat::Toml), "toml" => Ok(OutputFormat::Toml),
"csv" => Ok(OutputFormat::Csv), "csv" => Ok(OutputFormat::Csv),
"json" => Ok(OutputFormat::Json), "json" => Ok(OutputFormat::Json),
"plain" => Ok(OutputFormat::Plain), "plain" => Ok(OutputFormat::Plain),
format => Err(format!("Unknown output format {}", format).into()), format => Err(format!("Unknown output format {}", format).into()),
};
}
} }
} }


impl OutputFormat { impl OutputFormat {
fn as_accept_header(&self) -> header::HeaderValue { fn as_accept_header(&self) -> header::HeaderValue {
return header::HeaderValue::from_static(match self {
header::HeaderValue::from_static(match self {
OutputFormat::Json => "application/json", OutputFormat::Json => "application/json",
OutputFormat::Csv => "text/csv", OutputFormat::Csv => "text/csv",
OutputFormat::Toml => "application/toml", OutputFormat::Toml => "application/toml",
OutputFormat::Plain => "text/plain", OutputFormat::Plain => "text/plain",
});
})
} }
} }


@@ -91,18 +91,18 @@ impl DataSource {


if let Some(url) = url_arg { if let Some(url) = url_arg {
return Url::parse(&url) return Url::parse(&url)
.map(|parsed_url| DataSource::Url(parsed_url))
.map(DataSource::Url)
.map_err(|e| format!("Failed to parse {} as url: {}", url, e).into()); .map_err(|e| format!("Failed to parse {} as url: {}", url, e).into());
} }


return Err(GET_DATA_ARGUMENT_ERROR_MESSAGE.into());
Err(GET_DATA_ARGUMENT_ERROR_MESSAGE.into())
} }


fn get_cache_key(&self, format: &OutputFormat) -> u64 { fn get_cache_key(&self, format: &OutputFormat) -> u64 {
let mut hasher = DefaultHasher::new(); let mut hasher = DefaultHasher::new();
format.hash(&mut hasher); format.hash(&mut hasher);
self.hash(&mut hasher); self.hash(&mut hasher);
return hasher.finish();
hasher.finish()
} }
} }


@@ -123,10 +123,9 @@ fn get_data_source_from_args(
args: &HashMap<String, Value>, args: &HashMap<String, Value>,
) -> Result<DataSource> { ) -> Result<DataSource> {
let path_arg = optional_arg!(String, args.get("path"), GET_DATA_ARGUMENT_ERROR_MESSAGE); let path_arg = optional_arg!(String, args.get("path"), GET_DATA_ARGUMENT_ERROR_MESSAGE);

let url_arg = optional_arg!(String, args.get("url"), GET_DATA_ARGUMENT_ERROR_MESSAGE); let url_arg = optional_arg!(String, args.get("url"), GET_DATA_ARGUMENT_ERROR_MESSAGE);


return DataSource::from_args(path_arg, url_arg, content_path);
DataSource::from_args(path_arg, url_arg, content_path)
} }


fn read_data_file(base_path: &PathBuf, full_path: PathBuf) -> Result<String> { fn read_data_file(base_path: &PathBuf, full_path: PathBuf) -> Result<String> {
@@ -140,9 +139,9 @@ fn read_data_file(base_path: &PathBuf, full_path: PathBuf) -> Result<String> {
) )
.into()); .into());
} }
return read_file(&full_path).map_err(|e| {
read_file(&full_path).map_err(|e| {
format!("`load_data`: error {} loading file {}", full_path.to_str().unwrap(), e).into() format!("`load_data`: error {} loading file {}", full_path.to_str().unwrap(), e).into()
});
})
} }


fn get_output_format_from_args( fn get_output_format_from_args(
@@ -161,14 +160,14 @@ fn get_output_format_from_args(


let from_extension = if let DataSource::Path(path) = data_source { let from_extension = if let DataSource::Path(path) = data_source {
let extension_result: Result<&str> = let extension_result: Result<&str> =
path.extension().map(|extension| extension.to_str().unwrap()).ok_or(
format!("Could not determine format for {} from extension", path.display()).into(),
);
path.extension().map(|extension| extension.to_str().unwrap()).ok_or_else(|| {
format!("Could not determine format for {} from extension", path.display()).into()
});
extension_result? extension_result?
} else { } else {
"plain" "plain"
}; };
return OutputFormat::from_str(from_extension);
OutputFormat::from_str(from_extension)
} }


/// A global function to load data from a file or from a URL /// A global function to load data from a file or from a URL
@@ -231,7 +230,7 @@ pub fn make_load_data(content_path: PathBuf, base_path: PathBuf) -> GlobalFn {
fn load_json(json_data: String) -> Result<Value> { fn load_json(json_data: String) -> Result<Value> {
let json_content: Value = let json_content: Value =
serde_json::from_str(json_data.as_str()).map_err(|e| format!("{:?}", e))?; serde_json::from_str(json_data.as_str()).map_err(|e| format!("{:?}", e))?;
return Ok(json_content);
Ok(json_content)
} }


/// Parse a TOML string and convert it to a Tera Value /// Parse a TOML string and convert it to a Tera Value


+ 5
- 3
components/templates/src/global_fns/mod.rs View File

@@ -142,9 +142,11 @@ pub fn make_get_taxonomy(all_taxonomies: &[Taxonomy], library: &Library) -> Glob
let container = match taxonomies.get(&kind) { let container = match taxonomies.get(&kind) {
Some(c) => c, Some(c) => c,
None => { None => {
return Err(
format!("`get_taxonomy` received an unknown taxonomy as kind: {}", kind).into()
);
return Err(format!(
"`get_taxonomy` received an unknown taxonomy as kind: {}",
kind
)
.into());
} }
}; };




+ 3
- 6
src/cmd/serve.rs View File

@@ -502,12 +502,9 @@ fn detect_change_kind(pwd: &Path, path: &Path) -> (ChangeKind, PathBuf) {
/// Check if the directory at path contains any file /// Check if the directory at path contains any file
fn is_folder_empty(dir: &Path) -> bool { fn is_folder_empty(dir: &Path) -> bool {
// Can panic if we don't have the rights I guess? // Can panic if we don't have the rights I guess?
for _ in read_dir(dir).expect("Failed to read a directory to see if it was empty") {
// If we get there, that means we have a file
return false;
}

true
let files: Vec<_> =
read_dir(dir).expect("Failed to read a directory to see if it was empty").collect();
files.is_empty()
} }


#[cfg(test)] #[cfg(test)]


Loading…
Cancel
Save