2016-11-03 01:58:42 +01:00
|
|
|
use serde::{Serialize, Serializer};
|
2017-02-15 22:34:37 -05:00
|
|
|
use serde::ser::SerializeStruct;
|
2015-07-16 19:26:16 +02:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
2015-07-19 00:08:38 +02:00
|
|
|
#[derive(Debug, Clone)]
|
2015-09-11 20:52:55 +02:00
|
|
|
pub enum BookItem {
|
|
|
|
|
Chapter(String, Chapter), // String = section
|
|
|
|
|
Affix(Chapter),
|
|
|
|
|
Spacer,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub struct Chapter {
|
2015-07-18 00:04:20 +02:00
|
|
|
pub name: String,
|
|
|
|
|
pub path: PathBuf,
|
|
|
|
|
pub sub_items: Vec<BookItem>,
|
2015-07-16 19:26:16 +02:00
|
|
|
}
|
|
|
|
|
|
2015-07-19 00:08:38 +02:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub struct BookItems<'a> {
|
|
|
|
|
pub items: &'a [BookItem],
|
|
|
|
|
pub current_index: usize,
|
|
|
|
|
pub stack: Vec<(&'a [BookItem], usize)>,
|
2015-07-18 00:04:20 +02:00
|
|
|
}
|
2015-07-16 19:26:16 +02:00
|
|
|
|
2015-07-19 00:08:38 +02:00
|
|
|
|
2015-09-11 20:52:55 +02:00
|
|
|
impl Chapter {
|
2015-07-18 00:04:20 +02:00
|
|
|
pub fn new(name: String, path: PathBuf) -> Self {
|
2015-07-16 19:26:16 +02:00
|
|
|
|
2015-09-11 20:52:55 +02:00
|
|
|
Chapter {
|
2015-07-16 19:26:16 +02:00
|
|
|
name: name,
|
|
|
|
|
path: path,
|
|
|
|
|
sub_items: vec![],
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-19 00:08:38 +02:00
|
|
|
}
|
2015-07-16 19:26:16 +02:00
|
|
|
|
2015-07-19 00:08:38 +02:00
|
|
|
|
2016-11-03 01:58:42 +01:00
|
|
|
impl Serialize for Chapter {
|
2017-05-19 13:04:37 +02:00
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
|
where S: Serializer
|
|
|
|
|
{
|
|
|
|
|
let mut struct_ = serializer.serialize_struct("Chapter", 2)?;
|
|
|
|
|
struct_.serialize_field("name", &self.name)?;
|
|
|
|
|
struct_.serialize_field("path", &self.path)?;
|
2017-02-15 22:34:37 -05:00
|
|
|
struct_.end()
|
2015-07-18 00:04:20 +02:00
|
|
|
}
|
2015-07-19 00:08:38 +02:00
|
|
|
}
|
|
|
|
|
|
2015-07-18 00:04:20 +02:00
|
|
|
|
2015-07-19 00:08:38 +02:00
|
|
|
|
|
|
|
|
// Shamelessly copied from Rustbook
|
|
|
|
|
// (https://github.com/rust-lang/rust/blob/master/src/rustbook/book.rs)
|
|
|
|
|
impl<'a> Iterator for BookItems<'a> {
|
2015-09-11 20:52:55 +02:00
|
|
|
type Item = &'a BookItem;
|
2015-07-19 00:08:38 +02:00
|
|
|
|
2015-09-11 20:52:55 +02:00
|
|
|
fn next(&mut self) -> Option<&'a BookItem> {
|
2015-07-19 00:08:38 +02:00
|
|
|
loop {
|
|
|
|
|
if self.current_index >= self.items.len() {
|
|
|
|
|
match self.stack.pop() {
|
|
|
|
|
None => return None,
|
|
|
|
|
Some((parent_items, parent_idx)) => {
|
|
|
|
|
self.items = parent_items;
|
|
|
|
|
self.current_index = parent_idx + 1;
|
2016-03-17 22:31:28 +01:00
|
|
|
},
|
2015-07-19 00:08:38 +02:00
|
|
|
}
|
|
|
|
|
} else {
|
2017-02-15 22:01:26 -05:00
|
|
|
let cur = &self.items[self.current_index];
|
2015-07-19 00:08:38 +02:00
|
|
|
|
2015-09-16 22:46:23 -04:00
|
|
|
match *cur {
|
2017-05-19 13:04:37 +02:00
|
|
|
BookItem::Chapter(_, ref ch) |
|
|
|
|
|
BookItem::Affix(ref ch) => {
|
2015-09-11 20:52:55 +02:00
|
|
|
self.stack.push((self.items, self.current_index));
|
|
|
|
|
self.items = &ch.sub_items[..];
|
|
|
|
|
self.current_index = 0;
|
|
|
|
|
},
|
2015-09-16 22:46:23 -04:00
|
|
|
BookItem::Spacer => {
|
2015-09-11 20:52:55 +02:00
|
|
|
self.current_index += 1;
|
2016-03-17 22:31:28 +01:00
|
|
|
},
|
2015-07-19 00:08:38 +02:00
|
|
|
}
|
|
|
|
|
|
2016-03-17 22:31:28 +01:00
|
|
|
return Some(cur);
|
2015-07-19 00:08:38 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2015-07-16 19:26:16 +02:00
|
|
|
}
|