use thiserror::Error;
#[derive(Debug, Error)]
pub enum BookSourceError {
#[error("book source config error: {0}")]
Config(#[from] ConfigError),
#[error("rule eval error: {0}")]
Eval(#[from] EvalError),
#[error("fetch error: {0}")]
Fetch(#[from] FetchError),
#[error("book source missing config: {0}")]
Missing(&'static str),
}
impl BookSourceError {
pub fn is_challenge(&self) -> bool {
matches!(self, BookSourceError::Fetch(FetchError::Challenged(_)))
}
}
#[derive(Debug, Error)]
pub enum FetchError {
#[error("http error: {0}")]
Http(#[from] reqwest::Error),
#[error("invalid header: {0}")]
Header(String),
#[error("decode error: {0}")]
Decode(String),
#[error("blocked by anti-bot challenge: {0}")]
Challenged(String),
#[cfg(feature = "browser")]
#[error("browser solve error: {0}")]
Browser(String),
}
#[derive(Debug, Error)]
pub enum ConfigError {
#[error("invalid book source json: {0}")]
Json(#[from] serde_json::Error),
#[error("read book source file: {0}")]
Io(#[from] std::io::Error),
}
#[derive(Debug, Error)]
pub enum EvalError {
#[error("invalid css selector: {0}")]
Selector(String),
#[error("invalid regex: {0}")]
Regex(String),
#[error("jsonpath error: {0}")]
JsonPath(String),
#[error("xpath error: {0}")]
Xpath(String),
#[error("invalid json content: {0}")]
Json(String),
#[error("extraction backend not enabled: {0}")]
Unsupported(&'static str),
#[error("codec error: {0}")]
Codec(String),
#[error("crypto error: {0}")]
Crypto(String),
#[error("js error: {0}")]
Js(String),
#[error("font map error: {0}")]
Font(String),
}
pub type Result<T> = std::result::Result<T, BookSourceError>;