1pub mod engine;
20pub mod error;
21pub mod eval;
22pub mod fetch;
23#[cfg(feature = "js-host")]
24pub mod host;
25pub mod model;
26pub mod source;
27pub mod verify;
28
29pub use engine::Engine;
32pub use error::{BookSourceError, ConfigError, EvalError, FetchError, Result};
33pub use fetch::{FetchRequest, FetchResponse, Fetcher, ReqwestFetcher, is_challenge};
34pub use model::{BookInfo, BookList, BookListItem, Chapter, ExploreEntry, Toc, Volume};
35pub use source::{BookSource, FetchMode, UrlOrRule};
36pub use verify::{Check, CheckStatus, DiagnoseReport, VerifyReport, diagnose, verify_sample};
37
38pub use fetch::cookie;
41#[cfg(feature = "js-host")]
42pub use host::state;
43
44#[cfg(feature = "browser")]
46pub use fetch::browser::{
47 AuthDecision, BrowserCookie, BrowserFetcher, BrowserOptions, BrowserUi, Clearance,
48 EscalatingFetcher, LoginCriteria, LoginOutcome, LoginSignal, detect_browser,
49 shutdown_render_pool,
50};
51
52#[cfg(test)]
55pub(crate) mod testutil {
56 #![allow(dead_code)]
59
60 use crate::source::BookSource;
61 use std::io::{Read, Write};
62 use std::net::TcpListener;
63
64 pub(crate) fn book_source(base: &str) -> BookSource {
66 serde_json::from_value(serde_json::json!({
67 "schema": "trnovel-booksource/v2",
68 "name": "t",
69 "url": base,
70 "bookInfo": {},
71 "toc": {"list": {"via": "raw"}, "name": {"via": "raw"}, "url": {"via": "raw"}},
72 "content": {"value": {"via": "raw"}}
73 }))
74 .expect("minimal book source")
75 }
76
77 pub(crate) fn spawn_echo_server() -> (String, std::thread::JoinHandle<()>) {
79 let listener = TcpListener::bind("127.0.0.1:0").unwrap();
80 let base = format!("http://{}", listener.local_addr().unwrap());
81 let handle = std::thread::spawn(move || {
82 if let Ok((mut stream, _)) = listener.accept() {
83 let mut buf = [0u8; 8192];
84 let n = stream.read(&mut buf).unwrap_or(0);
85 let body = buf[..n].to_vec();
86 let head = format!(
87 "HTTP/1.1 200 OK\r\nContent-Type: text/plain; charset=utf-8\r\nContent-Length: {}\r\nConnection: close\r\n\r\n",
88 body.len()
89 );
90 let _ = stream.write_all(head.as_bytes());
91 let _ = stream.write_all(&body);
92 let _ = stream.flush();
93 }
94 });
95 (base, handle)
96 }
97
98 pub(crate) fn spawn_fixed_server(
100 raw_response: String,
101 ) -> (String, std::thread::JoinHandle<()>) {
102 let listener = TcpListener::bind("127.0.0.1:0").unwrap();
103 let base = format!("http://{}", listener.local_addr().unwrap());
104 let handle = std::thread::spawn(move || {
105 if let Ok((mut stream, _)) = listener.accept() {
106 let mut buf = [0u8; 4096];
107 let _ = stream.read(&mut buf);
108 let _ = stream.write_all(raw_response.as_bytes());
109 let _ = stream.flush();
110 }
111 });
112 (base, handle)
113 }
114}