use crate::imports::*;
use crate::utils::ErrorMap;
use percent_encoding::{utf8_percent_encode,NON_ALPHANUMERIC};
#[derive(Debug,Clone,Eq,PartialEq)]
#[derive(Serialize,Deserialize)]
pub struct Html(pub String);
#[derive(Debug,Eq,PartialEq)]
#[derive(Serialize,Deserialize)]
pub struct HtmlRef<'r>(pub &'r str);
impl Html {
pub fn from_literal(lit : &str) -> Html {
Html(htmlescape::encode_minimal(lit))
}
pub fn as_ref(&self) -> HtmlRef { HtmlRef(self.0.as_ref()) }
}
impl HtmlRef<'_> {
pub fn to_owned(&self) -> Html { Html(self.0.to_owned()) }
}
pub const INDEX_BASENAME : &str = "index";
pub const INDEX : &str = "index.html";
pub struct IndexWriter {
f : BufWriter<File>,
deferred_error : Result<(),io::Error>,
}
enum TableState {
Unstarted(Html),
Working,
}
use TableState::*;
pub struct TableWriter<'i> {
i : &'i mut IndexWriter,
s : TableState,
}
impl IndexWriter {
#[throws(E)]
pub fn new(outdir : &str, title : &HtmlRef) -> IndexWriter {
let f = File::create(outdir.to_owned() + "/" + INDEX).cxm(||format!(
"create index file {}", INDEX))?;
let mut f = BufWriter::new(f);
writeln!(&mut f,
r#"<html><head><title>{}</title><head><body>"#,
title.0)?;
IndexWriter { f, deferred_error : Ok(()) }
}
#[throws(E)]
fn check(&mut self) {
replace(&mut self.deferred_error, Ok(()))?;
}
#[throws(E)]
pub fn table(&mut self, heading : Html) -> TableWriter {
self.check()?;
TableWriter { i : self, s : Unstarted(heading) }
}
#[throws(E)]
pub fn finish(mut self) {
self.check()?;
writeln!(&mut self.f,
r#"</body></html>"#)?;
self.f.flush()?;
}
}
impl TableWriter<'_> {
#[throws(E)]
pub fn entry(&mut self, filename : &str, desc : &HtmlRef) {
match &mut self.s {
Unstarted(ref mut heading) => {
writeln!(&mut self.i.f,
r#"<h1>{}</h1><table>"#,
heading.0)?;
self.s = Working;
},
Working => { },
}
writeln!(&mut self.i.f,
r#"<tr><th align="left"><a href="{}">{}</a></th><td>{}</td>"#,
utf8_percent_encode(filename, NON_ALPHANUMERIC),
Html::from_literal(filename).0,
desc.0
)?;
}
}
impl Drop for TableWriter<'_> {
fn drop(&mut self) {
match self.s {
Unstarted(_) => { }
Working => {
self.i.deferred_error =
writeln!(&mut self.i.f, r#"</table>"#);
}
}
}
}