use std::fmt::{Debug, Display, Formatter};
use nom::Needed;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, BililiveError>;
pub enum IncompleteResult<T> {
Ok(T),
Incomplete(Needed),
Err(BililiveError),
}
#[derive(Debug, Error)]
pub enum ParseError {
#[error("json error: {0}")]
JSON(#[from] serde_json::Error),
#[error("not a valid int32 big endian")]
Int32BE,
#[error("error when parsing room id")]
RoomId,
#[error("unknown websocket pack protocol")]
UnknownProtocol,
#[error("error when parsing packet struct")]
PacketError(String),
#[error("error when decompressing packet buffer: {0}")]
ZlibError(#[from] std::io::Error),
}
pub enum HTTPError {
#[cfg(feature = "h1-client")]
HTTPClient(http_client::Error),
#[cfg(feature = "reqwest")]
Reqwest(reqwest::Error),
}
#[cfg(feature = "h1-client")]
#[allow(unreachable_patterns)]
impl HTTPError {
#[must_use]
pub fn inner(self) -> http_client::Error {
match self {
HTTPError::HTTPClient(e) => e,
_ => unreachable!(),
}
}
#[must_use]
pub fn inner_ref(&self) -> &http_client::Error {
match self {
HTTPError::HTTPClient(e) => e,
_ => unreachable!(),
}
}
}
#[cfg(all(not(feature = "h1-client"), feature = "reqwest"))]
#[allow(unreachable_patterns)]
impl HTTPError {
#[must_use]
pub fn inner(self) -> reqwest::Error {
match self {
HTTPError::Reqwest(e) => e,
_ => unreachable!(),
}
}
#[must_use]
pub fn inner_ref(&self) -> &reqwest::Error {
match self {
HTTPError::Reqwest(e) => e,
_ => unreachable!(),
}
}
}
#[cfg(feature = "h1-client")]
impl From<http_client::Error> for HTTPError {
fn from(e: http_client::Error) -> Self {
Self::HTTPClient(e)
}
}
#[cfg(feature = "reqwest")]
impl From<reqwest::Error> for HTTPError {
fn from(e: reqwest::Error) -> Self {
Self::Reqwest(e)
}
}
impl Debug for HTTPError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Debug::fmt(self.inner_ref(), f)
}
}
impl Display for HTTPError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Display::fmt(self.inner_ref(), f)
}
}
#[derive(Debug, Error)]
pub enum BililiveError {
#[error("http error: {0}")]
HTTP(HTTPError),
#[error("parse error: {0}")]
Parse(#[from] ParseError),
#[error("io error: {0}")]
IOError(#[from] std::io::Error),
#[error("build error: missing field {0}")]
Build(String),
#[error("websocket error: {0}")]
WebSocket(#[from] async_tungstenite::tungstenite::Error),
#[error("client not connected")]
NotConnected,
}
#[cfg(feature = "h1-client")]
impl From<http_client::Error> for BililiveError {
fn from(e: http_client::Error) -> Self {
Self::HTTP(e.into())
}
}
#[cfg(feature = "reqwest")]
impl From<reqwest::Error> for BililiveError {
fn from(e: reqwest::Error) -> Self {
Self::HTTP(e.into())
}
}