2015-09-05 17:26:17 +02:00
|
|
|
use std::path::Path;
|
2016-12-23 08:10:42 +00:00
|
|
|
use std::collections::{VecDeque, BTreeMap};
|
2015-07-31 18:34:43 +02:00
|
|
|
|
2016-11-03 01:58:42 +01:00
|
|
|
use serde_json;
|
|
|
|
|
use serde_json::value::ToJson;
|
2016-03-27 18:22:17 +02:00
|
|
|
use handlebars::{Handlebars, RenderError, RenderContext, Helper, Context, Renderable};
|
2015-07-31 18:34:43 +02:00
|
|
|
|
2016-12-23 08:10:42 +00:00
|
|
|
|
2015-07-31 18:34:43 +02:00
|
|
|
// Handlebars helper for navigation
|
|
|
|
|
|
2015-08-03 22:09:26 +02:00
|
|
|
pub fn previous(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
|
|
|
|
debug!("[fn]: previous (handlebars helper)");
|
2015-07-31 18:34:43 +02:00
|
|
|
|
2015-08-03 22:09:26 +02:00
|
|
|
debug!("[*]: Get data from context");
|
2015-07-31 18:34:43 +02:00
|
|
|
// get value from context data
|
|
|
|
|
// rc.get_path() is current json parent path, you should always use it like this
|
|
|
|
|
// param is the key of value you want to display
|
2016-12-23 08:10:42 +00:00
|
|
|
let chapters = c.navigate(rc.get_path(), &VecDeque::new(), "chapters");
|
2015-07-31 18:34:43 +02:00
|
|
|
|
2016-12-23 08:10:42 +00:00
|
|
|
let current = c.navigate(rc.get_path(), &VecDeque::new(), "path")
|
2016-08-01 14:06:08 +02:00
|
|
|
.to_string()
|
|
|
|
|
.replace("\"", "");
|
2015-07-31 18:34:43 +02:00
|
|
|
|
|
|
|
|
|
2015-08-03 22:09:26 +02:00
|
|
|
debug!("[*]: Decode chapters from JSON");
|
|
|
|
|
// Decode json format
|
2016-11-03 01:58:42 +01:00
|
|
|
let decoded: Vec<BTreeMap<String, String>> = match serde_json::from_str(&chapters.to_string()) {
|
2015-08-11 22:55:51 +02:00
|
|
|
Ok(data) => data,
|
2016-08-01 14:06:08 +02:00
|
|
|
Err(_) => return Err(RenderError::new("Could not decode the JSON data")),
|
2015-08-11 22:55:51 +02:00
|
|
|
};
|
2015-08-03 22:09:26 +02:00
|
|
|
let mut previous: Option<BTreeMap<String, String>> = None;
|
2015-07-31 18:34:43 +02:00
|
|
|
|
2015-08-11 22:55:51 +02:00
|
|
|
|
2015-08-03 22:09:26 +02:00
|
|
|
debug!("[*]: Search for current Chapter");
|
|
|
|
|
// Search for current chapter and return previous entry
|
2015-07-31 18:34:43 +02:00
|
|
|
for item in decoded {
|
|
|
|
|
|
2015-08-03 22:09:26 +02:00
|
|
|
match item.get("path") {
|
2015-09-16 22:46:23 -04:00
|
|
|
Some(path) if !path.is_empty() => {
|
2015-07-31 18:34:43 +02:00
|
|
|
if path == ¤t {
|
|
|
|
|
|
2015-08-03 22:09:26 +02:00
|
|
|
debug!("[*]: Found current chapter");
|
2016-03-17 22:31:28 +01:00
|
|
|
if let Some(previous) = previous {
|
2015-08-03 22:09:26 +02:00
|
|
|
|
|
|
|
|
debug!("[*]: Creating BTreeMap to inject in context");
|
|
|
|
|
// Create new BTreeMap to extend the context: 'title' and 'link'
|
|
|
|
|
let mut previous_chapter = BTreeMap::new();
|
|
|
|
|
|
2015-08-11 22:55:51 +02:00
|
|
|
// Chapter title
|
|
|
|
|
match previous.get("name") {
|
|
|
|
|
Some(n) => {
|
|
|
|
|
debug!("[*]: Inserting title: {}", n);
|
2015-09-16 22:46:23 -04:00
|
|
|
previous_chapter.insert("title".to_owned(), n.to_json())
|
2015-08-11 22:55:51 +02:00
|
|
|
},
|
|
|
|
|
None => {
|
|
|
|
|
debug!("[*]: No title found for chapter");
|
2016-08-01 14:06:08 +02:00
|
|
|
return Err(RenderError::new("No title found for chapter in JSON data"));
|
2016-03-17 22:31:28 +01:00
|
|
|
},
|
2015-08-11 22:55:51 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Chapter link
|
|
|
|
|
|
|
|
|
|
match previous.get("path") {
|
|
|
|
|
Some(p) => {
|
2016-04-25 17:02:47 +02:00
|
|
|
// Hack for windows who tends to use `\` as separator instead of `/`
|
2015-09-05 17:26:17 +02:00
|
|
|
let path = Path::new(p).with_extension("html");
|
2015-08-11 22:55:51 +02:00
|
|
|
debug!("[*]: Inserting link: {:?}", path);
|
|
|
|
|
|
|
|
|
|
match path.to_str() {
|
2016-03-17 22:31:28 +01:00
|
|
|
Some(p) => {
|
2016-04-25 17:02:47 +02:00
|
|
|
previous_chapter.insert("link".to_owned(), p.replace("\\", "/").to_json());
|
2016-03-17 22:31:28 +01:00
|
|
|
},
|
2016-08-01 14:06:08 +02:00
|
|
|
None => return Err(RenderError::new("Link could not be converted to str")),
|
2015-08-11 22:55:51 +02:00
|
|
|
}
|
|
|
|
|
},
|
2016-08-01 14:06:08 +02:00
|
|
|
None => return Err(RenderError::new("No path found for chapter in JSON data")),
|
2015-08-11 22:55:51 +02:00
|
|
|
}
|
2015-08-03 22:09:26 +02:00
|
|
|
|
|
|
|
|
debug!("[*]: Inject in context");
|
|
|
|
|
// Inject in current context
|
2015-08-04 12:51:07 +02:00
|
|
|
let updated_context = c.extend(&previous_chapter);
|
2015-08-03 22:09:26 +02:00
|
|
|
|
|
|
|
|
debug!("[*]: Render template");
|
|
|
|
|
// Render template
|
2015-08-11 22:55:51 +02:00
|
|
|
match _h.template() {
|
|
|
|
|
Some(t) => {
|
|
|
|
|
try!(t.render(&updated_context, r, rc));
|
|
|
|
|
},
|
2016-08-01 14:06:08 +02:00
|
|
|
None => return Err(RenderError::new("Error with the handlebars template")),
|
2015-08-11 22:55:51 +02:00
|
|
|
}
|
|
|
|
|
|
2015-08-03 22:09:26 +02:00
|
|
|
}
|
2015-07-31 18:34:43 +02:00
|
|
|
|
2015-08-03 22:09:26 +02:00
|
|
|
break;
|
2016-03-17 22:31:28 +01:00
|
|
|
} else {
|
2015-08-03 22:09:26 +02:00
|
|
|
previous = Some(item.clone());
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
_ => continue,
|
2015-08-11 22:55:51 +02:00
|
|
|
|
2015-07-31 18:34:43 +02:00
|
|
|
}
|
2015-08-11 22:55:51 +02:00
|
|
|
|
2015-07-31 18:34:43 +02:00
|
|
|
}
|
2015-08-11 22:55:51 +02:00
|
|
|
|
2015-07-31 18:34:43 +02:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-08-04 12:51:07 +02:00
|
|
|
pub fn next(c: &Context, _h: &Helper, r: &Handlebars, rc: &mut RenderContext) -> Result<(), RenderError> {
|
|
|
|
|
debug!("[fn]: next (handlebars helper)");
|
|
|
|
|
|
|
|
|
|
debug!("[*]: Get data from context");
|
2015-07-31 18:34:43 +02:00
|
|
|
// get value from context data
|
|
|
|
|
// rc.get_path() is current json parent path, you should always use it like this
|
|
|
|
|
// param is the key of value you want to display
|
2016-12-23 08:10:42 +00:00
|
|
|
let chapters = c.navigate(rc.get_path(), &VecDeque::new(), "chapters");
|
2015-07-31 18:34:43 +02:00
|
|
|
|
2016-12-23 08:10:42 +00:00
|
|
|
let current = c.navigate(rc.get_path(), &VecDeque::new(), "path")
|
2016-08-01 14:06:08 +02:00
|
|
|
.to_string()
|
|
|
|
|
.replace("\"", "");
|
2015-08-04 12:51:07 +02:00
|
|
|
|
|
|
|
|
debug!("[*]: Decode chapters from JSON");
|
|
|
|
|
// Decode json format
|
2016-11-03 01:58:42 +01:00
|
|
|
let decoded: Vec<BTreeMap<String, String>> = match serde_json::from_str(&chapters.to_string()) {
|
2015-08-11 22:55:51 +02:00
|
|
|
Ok(data) => data,
|
2016-08-01 14:06:08 +02:00
|
|
|
Err(_) => return Err(RenderError::new("Could not decode the JSON data")),
|
2015-08-11 22:55:51 +02:00
|
|
|
};
|
2015-08-04 12:51:07 +02:00
|
|
|
let mut previous: Option<BTreeMap<String, String>> = None;
|
2015-07-31 18:34:43 +02:00
|
|
|
|
2015-08-04 12:51:07 +02:00
|
|
|
debug!("[*]: Search for current Chapter");
|
|
|
|
|
// Search for current chapter and return previous entry
|
2015-07-31 18:34:43 +02:00
|
|
|
for item in decoded {
|
|
|
|
|
|
2015-08-04 12:51:07 +02:00
|
|
|
match item.get("path") {
|
|
|
|
|
|
2015-09-16 22:46:23 -04:00
|
|
|
Some(path) if !path.is_empty() => {
|
2015-08-04 12:51:07 +02:00
|
|
|
|
|
|
|
|
if let Some(previous) = previous {
|
2015-08-11 22:55:51 +02:00
|
|
|
|
2015-08-12 19:22:53 +02:00
|
|
|
let previous_path = match previous.get("path") {
|
2015-08-11 22:55:51 +02:00
|
|
|
Some(p) => p,
|
2016-08-01 14:06:08 +02:00
|
|
|
None => return Err(RenderError::new("No path found for chapter in JSON data")),
|
2015-08-11 22:55:51 +02:00
|
|
|
};
|
|
|
|
|
|
2015-08-12 19:22:53 +02:00
|
|
|
if previous_path == ¤t {
|
2015-08-04 12:51:07 +02:00
|
|
|
|
|
|
|
|
debug!("[*]: Found current chapter");
|
|
|
|
|
debug!("[*]: Creating BTreeMap to inject in context");
|
|
|
|
|
// Create new BTreeMap to extend the context: 'title' and 'link'
|
|
|
|
|
let mut next_chapter = BTreeMap::new();
|
|
|
|
|
|
2015-08-11 22:55:51 +02:00
|
|
|
match item.get("name") {
|
|
|
|
|
Some(n) => {
|
|
|
|
|
debug!("[*]: Inserting title: {}", n);
|
2015-09-16 22:46:23 -04:00
|
|
|
next_chapter.insert("title".to_owned(), n.to_json());
|
2016-03-17 22:31:28 +01:00
|
|
|
},
|
2016-08-01 14:06:08 +02:00
|
|
|
None => return Err(RenderError::new("No title found for chapter in JSON data")),
|
2015-08-11 22:55:51 +02:00
|
|
|
}
|
2015-08-04 12:51:07 +02:00
|
|
|
|
2015-08-12 19:22:53 +02:00
|
|
|
|
2015-09-05 17:26:17 +02:00
|
|
|
let link = Path::new(path).with_extension("html");
|
2015-08-11 22:55:51 +02:00
|
|
|
debug!("[*]: Inserting link: {:?}", link);
|
2015-08-04 12:51:07 +02:00
|
|
|
|
2015-08-11 22:55:51 +02:00
|
|
|
match link.to_str() {
|
2016-03-17 22:31:28 +01:00
|
|
|
Some(l) => {
|
2016-04-25 17:02:47 +02:00
|
|
|
// Hack for windows who tends to use `\` as separator instead of `/`
|
|
|
|
|
next_chapter.insert("link".to_owned(), l.replace("\\", "/").to_json());
|
2016-03-17 22:31:28 +01:00
|
|
|
},
|
2016-08-01 14:06:08 +02:00
|
|
|
None => return Err(RenderError::new("Link could not converted to str")),
|
2015-08-11 22:55:51 +02:00
|
|
|
}
|
2015-08-04 12:51:07 +02:00
|
|
|
|
|
|
|
|
debug!("[*]: Inject in context");
|
|
|
|
|
// Inject in current context
|
|
|
|
|
let updated_context = c.extend(&next_chapter);
|
|
|
|
|
|
|
|
|
|
debug!("[*]: Render template");
|
2015-08-11 22:55:51 +02:00
|
|
|
|
2015-08-04 12:51:07 +02:00
|
|
|
// Render template
|
2015-08-11 22:55:51 +02:00
|
|
|
match _h.template() {
|
|
|
|
|
Some(t) => {
|
|
|
|
|
try!(t.render(&updated_context, r, rc));
|
|
|
|
|
},
|
2016-08-01 14:06:08 +02:00
|
|
|
None => return Err(RenderError::new("Error with the handlebars template")),
|
2015-08-11 22:55:51 +02:00
|
|
|
}
|
2015-08-04 12:51:07 +02:00
|
|
|
|
2016-03-17 22:31:28 +01:00
|
|
|
break;
|
2015-08-04 12:51:07 +02:00
|
|
|
}
|
2015-07-31 18:34:43 +02:00
|
|
|
}
|
2015-08-04 12:51:07 +02:00
|
|
|
|
|
|
|
|
previous = Some(item.clone());
|
|
|
|
|
},
|
2015-08-11 22:55:51 +02:00
|
|
|
|
2015-08-04 12:51:07 +02:00
|
|
|
_ => continue,
|
2015-07-31 18:34:43 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|