use crate::dom::Dom;
use crate::error::Result;
use crate::options::{Options, ReaderableOptions};
use crate::readability::{Article, Readability};
use crate::readerable::is_probably_readerable_doc;
pub struct Document<'a> {
pub(crate) doc: Dom,
html: &'a str,
}
impl<'a> Document<'a> {
pub fn new(html: &'a str) -> Self {
Self {
doc: Dom::parse_document(html).expect("HTML DOM node limit exceeded"),
html,
}
}
pub fn is_probably_readerable(&self, options: Option<ReaderableOptions>) -> bool {
is_probably_readerable_doc(&self.doc, options)
}
pub fn parse(self, url: Option<&str>, options: Option<Options>) -> Result<Article> {
let options = options.unwrap_or_default();
Readability::from_document(self.doc, self.html, url, &options).parse()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_readerable_check() {
let s = "a ".repeat(300);
assert!(Document::new(&format!("<p>{s}</p>")).is_probably_readerable(None));
}
#[test]
fn test_not_readerable() {
assert!(!Document::new("<p>Short</p>").is_probably_readerable(None));
}
#[test]
fn empty_documents_have_no_content() {
for html in [
"",
"<html><head><title>No body content</title></head></html>",
"<html><body><img src=\"article.jpg\" alt=\"Article image\"></body></html>",
] {
assert!(matches!(
Document::new(html).parse(None, None),
Err(crate::Error::NoContent)
));
}
}
}