mod prelude {
pub use reqwest::{Client, Response, StatusCode};
pub use serde::de::DeserializeOwned;
pub use std::{future::Future, pin::Pin};
pub use crate::{Error, Result};
pub(super) use super::BiliResponseExt;
pub use super::{Request, RequestResponse};
}
use prelude::*;
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct BiliResponse<T> {
code: i64,
#[serde(default)]
message: String,
#[serde(bound(deserialize = "T: serde::Deserialize<'de>"))]
#[serde(default = "Option::default")]
data: Option<T>,
}
impl<T: DeserializeOwned> BiliResponse<T> {
#[allow(unused)]
pub fn into_data(self) -> Option<T> {
self.data
}
pub async fn from_response(response: Response) -> Result<T> {
if response.status() != StatusCode::OK {
let status = response.status();
#[cfg(debug_assertions)]
debug!(
"status = {:?}, response text = {:?}",
status,
response.text().await
);
return Err(Error::StatusCode(status));
}
let response_text = response.text().await?;
let this: Self = serde_json::from_str(&response_text).map_err(|e| {
debug!("response text = {}", response_text);
e
})?;
if this.code != 0 {
debug!("response text = {}", response_text);
return Err(Error::BiliCustom {
code: this.code,
message: this.message,
});
}
match this.data {
Some(data) => Ok(data),
None => Err(Error::DataNotFound),
}
}
}
pub trait BiliResponseExt {
fn bili_data<T: DeserializeOwned>(self) -> Pin<Box<dyn Future<Output = Result<T>> + Send>>;
}
impl BiliResponseExt for Response {
fn bili_data<T: DeserializeOwned>(self) -> Pin<Box<dyn Future<Output = Result<T>> + Send>> {
Box::pin(async move { BiliResponse::<T>::from_response(self).await })
}
}
pub trait Request: DeserializeOwned {
type Args;
fn request(client: &Client, args: Self::Args) -> RequestResponse<Self>;
}
pub type RequestResponse<T> = Pin<Box<dyn Future<Output = Result<T>> + Send>>;
mod room_info;
pub use room_info::{InfoByRoom, RoomInfo};
mod danmu_info;
pub use danmu_info::{DanmuInfo, DanmuServer};
mod video_info;
pub use video_info::{VideoInfo, VideoPage, VideoStat};
mod login;
pub use login::{CheckQrLogin, QrLoginRequest};
mod uploader_stat;
pub use uploader_stat::UploaderStat;
mod user_info;
pub use user_info::UserInfo;
mod vote_info;
pub use vote_info::VoteInfo;
mod my_account_info;
pub use my_account_info::MyAccountInfo;