refactor: 用更 idiomatic 的方式改写一些代码 (#54)

* refactor: Config 采用 arc_swap 而非锁

* refactor: 改进 config 的检查,及其他一些细微优化

* refactor: 不再拆分 lib.rs 和 main.rs
This commit is contained in:
idlercloud
2024-04-04 18:39:41 +08:00
committed by GitHub
parent 2521fe932b
commit 4ba23ce8fc
12 changed files with 279 additions and 255 deletions

View File

@@ -1,3 +1,5 @@
use std::sync::Arc;
use anyhow::Result;
use reqwest::{header, Method};
@@ -54,31 +56,30 @@ impl Default for Client {
}
pub struct BiliClient {
credential: Option<Credential>,
client: Client,
}
impl BiliClient {
pub fn new(credential: Option<Credential>) -> Self {
pub fn new() -> Self {
let client = Client::new();
Self { credential, client }
Self { client }
}
pub fn request(&self, method: Method, url: &str) -> reqwest::RequestBuilder {
self.client.request(method, url, self.credential.as_ref())
let credential = CONFIG.credential.load();
self.client.request(method, url, credential.as_deref())
}
pub async fn check_refresh(&mut self) -> Result<()> {
let Some(credential) = self.credential.as_mut() else {
pub async fn check_refresh(&self) -> Result<()> {
let credential = CONFIG.credential.load();
let Some(credential) = credential.as_deref() else {
return Ok(());
};
if !credential.need_refresh(&self.client).await? {
return Ok(());
}
credential.refresh(&self.client).await?;
let mut config = CONFIG.lock().unwrap();
config.credential = Some(credential.clone());
config.save()
let new_credential = credential.refresh(&self.client).await?;
CONFIG.credential.store(Some(Arc::new(new_credential)));
CONFIG.save()
}
}

View File

@@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize};
use super::error::BiliError;
use crate::bilibili::Client;
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Credential {
pub sessdata: String,
pub bili_jct: String,
@@ -32,6 +32,16 @@ impl Credential {
}
}
const fn empty() -> Self {
Self {
sessdata: String::new(),
bili_jct: String::new(),
buvid3: String::new(),
dedeuserid: String::new(),
ac_time_value: String::new(),
}
}
/// 检查凭据是否有效
pub async fn need_refresh(&self, client: &Client) -> Result<bool> {
let res = client
@@ -55,13 +65,12 @@ impl Credential {
res["data"]["refresh"].as_bool().ok_or(anyhow!("check refresh failed"))
}
pub async fn refresh(&mut self, client: &Client) -> Result<()> {
pub async fn refresh(&self, client: &Client) -> Result<Self> {
let correspond_path = Self::get_correspond_path();
let csrf = self.get_refresh_csrf(client, correspond_path).await?;
let new_credential = self.get_new_credential(client, &csrf).await?;
self.confirm_refresh(client, &new_credential).await?;
*self = new_credential;
Ok(())
Ok(new_credential)
}
fn get_correspond_path() -> String {
@@ -125,9 +134,9 @@ JNrRuoEUXpabUzGB8QIDAQAB
bail!(BiliError::RequestFailed(code, msg.to_owned()));
}
let set_cookies = headers.get_all(header::SET_COOKIE);
let mut credential = Credential {
let mut credential = Self {
buvid3: self.buvid3.clone(),
..Default::default()
..Self::empty()
};
let required_cookies = HashSet::from(["SESSDATA", "bili_jct", "DedeUserID"]);
let cookies: Vec<Cookie> = set_cookies

View File

@@ -3,7 +3,6 @@ use async_stream::stream;
use chrono::serde::ts_seconds;
use chrono::{DateTime, Utc};
use futures::Stream;
use log::error;
use serde_json::Value;
use crate::bilibili::error::BiliError;