-
Notifications
You must be signed in to change notification settings - Fork 1
/
docket.rs
70 lines (64 loc) · 1.93 KB
/
docket.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use std::{
fs, io,
path::{self, Path},
};
use log::trace;
use crate::{
doctree::{self, Bale},
error::{Error, Result as DocketResult},
render,
};
/// Docket
///
/// Represents a documentation set. Responsible for opening the bales of
/// documentation and traversing them to render out to HTML.
#[derive(Debug)]
pub struct Docket {
title: String,
doctree_root: Bale,
}
impl Docket {
/// Open the given `path` as a documentaiton collection
///
/// Once opned a documentaiton collection has a title, and can be rendreed
/// to a target path.
pub fn open<P: AsRef<Path>>(path: P) -> DocketResult<Self> {
if !path.as_ref().is_dir() {
Err(Error::SourcePathNotADirectory(path.as_ref().into()))?;
}
Ok(Docket {
title: title_from_path(path.as_ref())?,
doctree_root: doctree::open(&path)?,
})
}
/// Render to HTML
///
/// Renders the documentation set. Creates a tree of HTML files into the
/// given `target` directory.
pub fn render<P: AsRef<Path>>(self, target: P) -> DocketResult<()> {
trace!(
"Rendering documentation for {} to {:?}",
self.title,
target.as_ref()
);
render::render(target, self.title, self.doctree_root)?;
Ok(())
}
}
/// Calculate the title of the documentation set from the given path.
fn title_from_path(path: &Path) -> std::result::Result<String, io::Error> {
let title_file = path.join("title");
Ok(if title_file.is_file() {
fs::read_to_string(title_file)?
} else {
Path::canonicalize(path)?
.components()
.filter_map(|c| match c {
path::Component::Normal(path) => path.to_owned().into_string().ok(),
_ => None,
})
.filter(|s| s != "docs")
.last()
.unwrap_or_else(|| String::from("Documentation"))
})
}