use std::fmt::{Debug, Formatter};
use regex::Regex;
use scraper::Html;
use crate::backends::{
freewebnovel, Backend, BackendError, ChapterListElem, ChapterOrderingFn, FreeWebNovel,
};
use crate::utils::get;
use crate::Chapter;
pub struct LibRead {
url: String,
page: Html,
}
#[allow(unused_variables, dead_code)]
impl Debug for LibRead {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
#[derive(Debug)]
struct LibRead<'a> {
url: &'a String,
}
let Self { url, page: _ } = self;
Debug::fmt(&LibRead { url }, f)
}
}
impl Default for LibRead {
fn default() -> Self {
Self {
url: "".to_string(),
page: Html::new_document(),
}
}
}
impl Backend for LibRead {
fn get_backend_regexps() -> Vec<Regex> {
vec![Regex::new(r"https?://libread\.com/libread/\w+").unwrap()]
}
fn get_backend_name() -> &'static str {
"libread"
}
fn get_ordering_function() -> ChapterOrderingFn {
FreeWebNovel::get_ordering_function()
}
fn new(url: &str) -> Result<Self, BackendError> {
let req = get(url)?;
if !req.status().is_success() {
return Err(BackendError::RequestFailed {
message: format!("Could not fetch url {url}"),
status: req.status(),
content: req.text()?,
});
}
Ok(Self {
url: url.to_string(),
page: Html::parse_document(&req.text()?),
})
}
fn title(&self) -> Result<String, BackendError> {
freewebnovel::title(&self.page)
}
fn immutable_identifier(&self) -> Result<String, BackendError> {
Ok(self.url.split('/').last().unwrap().to_string())
}
fn url(&self) -> String {
self.url.clone()
}
fn cover_url(&self) -> Result<String, BackendError> {
freewebnovel::get_cover_url(&self.page)
}
fn get_authors(&self) -> Result<Vec<String>, BackendError> {
freewebnovel::authors(&self.page)
}
fn get_chapter_list(&self) -> Result<Vec<ChapterListElem>, BackendError> {
freewebnovel::get_chapter_list(&self.page)
}
fn get_chapter(&self, chapter_number: usize) -> Result<Chapter, BackendError> {
if chapter_number == 0 {
return Err(BackendError::UnknownChapter(chapter_number));
}
let chapter_url = self
.page
.select(&freewebnovel::CHAPTER_LIST_SELECTOR)
.map(|select| select.attr("href").unwrap())
.nth(chapter_number - 1)
.ok_or(BackendError::UnknownChapter(chapter_number))?;
let chapter_url = format!("https://libread.com{}", chapter_url);
println!("{:?}", chapter_url);
let mut chapter = freewebnovel::get_chapter(chapter_url)?;
chapter.index = chapter_number;
chapter.fiction_url = self.url.clone();
Ok(chapter)
}
fn get_chapter_count(&self) -> Result<usize, BackendError> {
freewebnovel::chapter_count(&self.page)
}
}
#[cfg(test)]
mod tests {
use std::str::FromStr;
use test_log::test;
use crate::backends::LibRead;
use crate::{Backend, Chapter};
#[test]
fn test_chapter_to_string_and_back() {
let b =
LibRead::new("https://libread.com/libread/the-guide-to-conquering-earthlings-33024")
.unwrap();
let chapter = b.get_chapter(1).unwrap();
let s = chapter.to_string();
let chapter2 = Chapter::from_str(&s).unwrap();
assert_eq!(chapter, chapter2);
}
}