//! Tables of contents and `encryption.xml`, read. #![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)] use std::io::{Cursor, Write}; use craft_epub::{Encrypted, Epub, MAX_TOC_ENTRIES, TocEntry, parse_encryption, parse_nav, parse_ncx}; fn zip_of(entries: &[(&str, &[u8])]) -> Vec { let mut z = zip::ZipWriter::new(Cursor::new(Vec::new())); let o = zip::write::SimpleFileOptions::default(); for (name, data) in entries { z.start_file(*name, o).unwrap(); z.write_all(data).unwrap(); } z.finish().unwrap().into_inner() } const CONTAINER: &[u8] = br#""#; fn e(label: &str, path: Option<&str>, fragment: Option<&str>, level: u8) -> TocEntry { TocEntry { label: label.into(), path: path.map(str::to_string), fragment: fragment.map(str::to_string), level } } const NAV: &[u8] = br##" "##; #[test] fn a_navigation_document_is_flattened_with_levels() { let toc = parse_nav(NAV, "OPS/nav/nav.xhtml").unwrap(); assert_eq!( toc, [ e("Chapter One & more", Some("OPS/text/c1.xhtml"), Some("start"), 1), e("Section", Some("OPS/nav/c 1.xhtml"), None, 2), e("Not a link", None, None, 2), e("Deep", Some("OPS/nav/nav.xhtml"), Some("local"), 3), e("Two", Some("abs.xhtml"), None, 1), ] ); // Without a `toc` the first `nav` is used; without any there is no table of contents. assert_eq!(parse_nav(br#""#, "nav.xhtml").unwrap().len(), 1); assert_eq!(parse_nav(b"", "nav.xhtml").unwrap(), []); assert_eq!(parse_nav(b"