From 1a32e38dc387e2f2cd3812da1e6ad263a00d7f1e Mon Sep 17 00:00:00 2001 From: amtoaer Date: Tue, 21 Jan 2025 18:06:54 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=BD=BF=E7=94=A8=20context=20?= =?UTF-8?q?=E4=BB=A3=E6=9B=BF=20ok=5For=20=E5=92=8C=20ok=5For=5Felse?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/bili_sync/src/adapter/collection.rs | 4 ++-- crates/bili_sync/src/adapter/favorite.rs | 4 ++-- crates/bili_sync/src/adapter/submission.rs | 4 ++-- crates/bili_sync/src/adapter/watch_later.rs | 4 ++-- crates/bili_sync/src/bilibili/analyzer.rs | 22 ++++++++++----------- crates/bili_sync/src/bilibili/client.rs | 6 ++---- crates/bili_sync/src/bilibili/credential.rs | 15 +++++++------- crates/bili_sync/src/bilibili/mod.rs | 6 ++---- crates/bili_sync/src/bilibili/video.rs | 15 +++++++------- crates/bili_sync/src/workflow.rs | 17 +++++++--------- 10 files changed, 44 insertions(+), 53 deletions(-) diff --git a/crates/bili_sync/src/adapter/collection.rs b/crates/bili_sync/src/adapter/collection.rs index 3176083..1a75eff 100644 --- a/crates/bili_sync/src/adapter/collection.rs +++ b/crates/bili_sync/src/adapter/collection.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use std::path::Path; use std::pin::Pin; -use anyhow::{anyhow, Result}; +use anyhow::{Context, Result}; use async_trait::async_trait; use bili_sync_entity::*; use futures::Stream; @@ -196,7 +196,7 @@ pub(super) async fn collection_from<'a>( ) .one(connection) .await? - .ok_or(anyhow!("collection not found"))?, + .context("collection not found")?, ), Box::pin(collection.into_simple_video_stream()), )) diff --git a/crates/bili_sync/src/adapter/favorite.rs b/crates/bili_sync/src/adapter/favorite.rs index 9bc0f61..8e672ef 100644 --- a/crates/bili_sync/src/adapter/favorite.rs +++ b/crates/bili_sync/src/adapter/favorite.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use std::path::Path; use std::pin::Pin; -use anyhow::{anyhow, Result}; +use anyhow::{Context, Result}; use async_trait::async_trait; use bili_sync_entity::*; use futures::Stream; @@ -153,7 +153,7 @@ pub(super) async fn favorite_from<'a>( .filter(favorite::Column::FId.eq(favorite_info.id)) .one(connection) .await? - .ok_or(anyhow!("favorite not found"))?, + .context("favorite not found")?, ), Box::pin(favorite.into_video_stream()), )) diff --git a/crates/bili_sync/src/adapter/submission.rs b/crates/bili_sync/src/adapter/submission.rs index ebe6149..805941b 100644 --- a/crates/bili_sync/src/adapter/submission.rs +++ b/crates/bili_sync/src/adapter/submission.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use std::path::Path; use std::pin::Pin; -use anyhow::{anyhow, Result}; +use anyhow::{Context, Result}; use async_trait::async_trait; use bili_sync_entity::*; use futures::Stream; @@ -169,7 +169,7 @@ pub(super) async fn submission_from<'a>( .filter(submission::Column::UpperId.eq(upper.mid)) .one(connection) .await? - .ok_or(anyhow!("submission not found"))?, + .context("submission not found")?, ), Box::pin(submission.into_video_stream()), )) diff --git a/crates/bili_sync/src/adapter/watch_later.rs b/crates/bili_sync/src/adapter/watch_later.rs index 195151c..d0d2c5d 100644 --- a/crates/bili_sync/src/adapter/watch_later.rs +++ b/crates/bili_sync/src/adapter/watch_later.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use std::path::Path; use std::pin::Pin; -use anyhow::{anyhow, Result}; +use anyhow::{Context, Result}; use async_trait::async_trait; use bili_sync_entity::*; use futures::Stream; @@ -151,7 +151,7 @@ pub(super) async fn watch_later_from<'a>( .filter(watch_later::Column::Id.eq(1)) .one(connection) .await? - .ok_or(anyhow!("watch_later not found"))?, + .context("watch_later not found")?, ), Box::pin(watch_later.into_video_stream()), )) diff --git a/crates/bili_sync/src/bilibili/analyzer.rs b/crates/bili_sync/src/bilibili/analyzer.rs index 660fa9b..1f314d4 100644 --- a/crates/bili_sync/src/bilibili/analyzer.rs +++ b/crates/bili_sync/src/bilibili/analyzer.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, bail, Result}; +use anyhow::{bail, Context, Result}; use serde::{Deserialize, Serialize}; use crate::bilibili::error::BiliError; @@ -160,7 +160,7 @@ impl PageAnalyzer { return Ok(vec![Stream::Flv( self.info["durl"][0]["url"] .as_str() - .ok_or(anyhow!("invalid flv stream"))? + .context("invalid flv stream")? .to_string(), )]); } @@ -168,7 +168,7 @@ impl PageAnalyzer { return Ok(vec![Stream::Html5Mp4( self.info["durl"][0]["url"] .as_str() - .ok_or(anyhow!("invalid html5 mp4 stream"))? + .context("invalid html5 mp4 stream")? .to_string(), )]); } @@ -176,7 +176,7 @@ impl PageAnalyzer { return Ok(vec![Stream::EpositeTryMp4( self.info["durl"][0]["url"] .as_str() - .ok_or(anyhow!("invalid episode try mp4 stream"))? + .context("invalid episode try mp4 stream")? .to_string(), )]); } @@ -193,7 +193,7 @@ impl PageAnalyzer { ) else { continue; }; - let quality = VideoQuality::from_repr(quality as usize).ok_or(anyhow!("invalid video stream quality"))?; + let quality = VideoQuality::from_repr(quality as usize).context("invalid video stream quality")?; // 从视频流的 codecs 字段中获取编码格式,此处并非精确匹配而是判断包含,比如 codecs 是 av1.42c01e,需要匹配为 av1 let Some(codecs) = [VideoCodecs::HEV, VideoCodecs::AVC, VideoCodecs::AV1] .into_iter() @@ -221,8 +221,7 @@ impl PageAnalyzer { let (Some(url), Some(quality)) = (audio["baseUrl"].as_str(), audio["id"].as_u64()) else { continue; }; - let quality = - AudioQuality::from_repr(quality as usize).ok_or(anyhow!("invalid audio stream quality"))?; + let quality = AudioQuality::from_repr(quality as usize).context("invalid audio stream quality")?; if quality < filter_option.audio_min_quality || quality > filter_option.audio_max_quality { continue; } @@ -237,7 +236,7 @@ impl PageAnalyzer { let (Some(url), Some(quality)) = (flac["baseUrl"].as_str(), flac["id"].as_u64()) else { bail!("invalid flac stream"); }; - let quality = AudioQuality::from_repr(quality as usize).ok_or(anyhow!("invalid flac stream quality"))?; + let quality = AudioQuality::from_repr(quality as usize).context("invalid flac stream quality")?; if quality >= filter_option.audio_min_quality && quality <= filter_option.audio_max_quality { streams.push(Stream::DashAudio { url: url.to_string(), @@ -250,8 +249,7 @@ impl PageAnalyzer { let (Some(url), Some(quality)) = (dolby_audio["baseUrl"].as_str(), dolby_audio["id"].as_u64()) else { bail!("invalid dolby audio stream"); }; - let quality = - AudioQuality::from_repr(quality as usize).ok_or(anyhow!("invalid dolby audio stream quality"))?; + let quality = AudioQuality::from_repr(quality as usize).context("invalid dolby audio stream quality")?; if quality >= filter_option.audio_min_quality && quality <= filter_option.audio_max_quality { streams.push(Stream::DashAudio { url: url.to_string(), @@ -267,7 +265,7 @@ impl PageAnalyzer { if self.is_flv_stream() || self.is_html5_mp4_stream() || self.is_episode_try_mp4_stream() { // 按照 streams 中的假设,符合这三种情况的流只有一个,直接取 return Ok(BestStream::Mixed( - streams.into_iter().next().ok_or(anyhow!("no stream found"))?, + streams.into_iter().next().context("no stream found")?, )); } let (videos, audios): (Vec, Vec) = @@ -297,7 +295,7 @@ impl PageAnalyzer { } _ => unreachable!(), }) - .ok_or(anyhow!("no video stream found"))?, + .context("no video stream found")?, audio: Iterator::max_by(audios.into_iter(), |a, b| match (a, b) { (Stream::DashAudio { quality: a_quality, .. }, Stream::DashAudio { quality: b_quality, .. }) => { a_quality.cmp(b_quality) diff --git a/crates/bili_sync/src/bilibili/client.rs b/crates/bili_sync/src/bilibili/client.rs index 4ed4a34..28ff71a 100644 --- a/crates/bili_sync/src/bilibili/client.rs +++ b/crates/bili_sync/src/bilibili/client.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use std::time::Duration; -use anyhow::{bail, Result}; +use anyhow::{Context, Result}; use leaky_bucket::RateLimiter; use reqwest::{header, Method}; @@ -109,9 +109,7 @@ impl BiliClient { /// 获取 wbi img,用于生成请求签名 pub async fn wbi_img(&self) -> Result { let credential = CONFIG.credential.load(); - let Some(credential) = credential.as_deref() else { - bail!("no credential found"); - }; + let credential = credential.as_deref().context("no credential found")?; credential.wbi_img(&self.client).await } } diff --git a/crates/bili_sync/src/bilibili/credential.rs b/crates/bili_sync/src/bilibili/credential.rs index 876f246..a50e2ca 100644 --- a/crates/bili_sync/src/bilibili/credential.rs +++ b/crates/bili_sync/src/bilibili/credential.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; use std::collections::HashSet; -use anyhow::{anyhow, bail, Result}; +use anyhow::{bail, ensure, Context, Result}; use cookie::Cookie; use regex::Regex; use reqwest::{header, Method}; @@ -74,7 +74,7 @@ impl Credential { .json::() .await? .validate()?; - res["data"]["refresh"].as_bool().ok_or(anyhow!("check refresh failed")) + res["data"]["refresh"].as_bool().context("check refresh failed") } pub async fn refresh(&self, client: &Client) -> Result { @@ -152,9 +152,10 @@ JNrRuoEUXpabUzGB8QIDAQAB .filter_map(|x| Cookie::parse(x).ok()) .filter(|x| required_cookies.contains(x.name())) .collect(); - if cookies.len() != required_cookies.len() { - bail!("not all required cookies found"); - } + ensure!( + cookies.len() == required_cookies.len(), + "not all required cookies found" + ); for cookie in cookies { match cookie.name() { "SESSDATA" => credential.sessdata = cookie.value().to_string(), @@ -197,9 +198,9 @@ fn regex_find(pattern: &str, doc: &str) -> Result { let re = Regex::new(pattern)?; Ok(re .captures(doc) - .ok_or_else(|| anyhow!("no match found"))? + .context("no match found")? .get(1) - .ok_or_else(|| anyhow!("no capture found"))? + .context("no capture found")? .as_str() .to_string()) } diff --git a/crates/bili_sync/src/bilibili/mod.rs b/crates/bili_sync/src/bilibili/mod.rs index db8c2c1..280e67e 100644 --- a/crates/bili_sync/src/bilibili/mod.rs +++ b/crates/bili_sync/src/bilibili/mod.rs @@ -1,7 +1,7 @@ use std::sync::Arc; pub use analyzer::{BestStream, FilterOption}; -use anyhow::{bail, Result}; +use anyhow::{bail, ensure, Result}; use arc_swap::ArcSwapOption; use chrono::serde::ts_seconds; use chrono::{DateTime, Utc}; @@ -49,9 +49,7 @@ impl Validate for serde_json::Value { (Some(code), Some(msg)) => (code, msg), _ => bail!("no code or message found"), }; - if code != 0 { - bail!(BiliError::RequestFailed(code, msg.to_owned())); - } + ensure!(code == 0, BiliError::RequestFailed(code, msg.to_owned())); Ok(self) } } diff --git a/crates/bili_sync/src/bilibili/video.rs b/crates/bili_sync/src/bilibili/video.rs index 3c39b56..e258892 100644 --- a/crates/bili_sync/src/bilibili/video.rs +++ b/crates/bili_sync/src/bilibili/video.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Result}; +use anyhow::{ensure, Result}; use futures::stream::FuturesUnordered; use futures::TryStreamExt; use prost::Message; @@ -130,13 +130,12 @@ impl<'a> Video<'a> { .error_for_status()?; let headers = std::mem::take(res.headers_mut()); let content_type = headers.get("content-type"); - if content_type.is_none_or(|v| v != "application/octet-stream") { - bail!( - "unexpected content type: {:?}, body: {:?}", - content_type, - res.text().await - ); - } + ensure!( + content_type.is_some_and(|v| v == "application/octet-stream"), + "unexpected content type: {:?}, body: {:?}", + content_type, + res.text().await + ); Ok(DmSegMobileReply::decode(res.bytes().await?)?.elems) } diff --git a/crates/bili_sync/src/workflow.rs b/crates/bili_sync/src/workflow.rs index d25c783..63ba0bb 100644 --- a/crates/bili_sync/src/workflow.rs +++ b/crates/bili_sync/src/workflow.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::pin::Pin; -use anyhow::{anyhow, bail, Result}; +use anyhow::{bail, Context, Result}; use bili_sync_entity::*; use futures::stream::{FuturesOrdered, FuturesUnordered}; use futures::{Future, Stream, StreamExt}; @@ -151,18 +151,15 @@ pub async fn download_video_pages( upper_path: &Path, upper_mutex: &(Mutex<()>, Mutex<()>), ) -> Result { - let permit = semaphore.acquire().await; - if let Err(e) = permit { - bail!(e); - } + let _permit = semaphore.acquire().await.context("acquire semaphore failed")?; let mut status = VideoStatus::new(video_model.download_status); let seprate_status = status.should_run(); let base_path = Path::new(&video_model.path); let upper_id = video_model.upper_id.to_string(); let base_upper_path = upper_path - .join(upper_id.chars().next().ok_or(anyhow!("upper_id is empty"))?.to_string()) + .join(upper_id.chars().next().context("upper_id is empty")?.to_string()) .join(upper_id); - let is_single_page = video_model.single_page.ok_or(anyhow!("single_page is null"))?; + let is_single_page = video_model.single_page.context("single_page is null")?; // 对于单页视频,page 的下载已经足够 // 对于多页视频,page 下载仅包含了分集内容,需要额外补上视频的 poster 的 tvshow.nfo let tasks: Vec>>>> = vec![ @@ -308,7 +305,7 @@ pub async fn download_page( } let mut status = PageStatus::new(page_model.download_status); let seprate_status = status.should_run(); - let is_single_page = video_model.single_page.ok_or(anyhow!("single_page is null"))?; + let is_single_page = video_model.single_page.context("single_page is null")?; let base_path = Path::new(&video_model.path); let base_name = TEMPLATE.path_safe_render( "page", @@ -428,7 +425,7 @@ pub async fn fetch_page_poster( if !should_run { return Ok(()); } - let single_page = video_model.single_page.ok_or(anyhow!("single_page is null"))?; + let single_page = video_model.single_page.context("single_page is null")?; let url = if single_page { // 单页视频直接用视频的封面 video_model.cover.as_str() @@ -516,7 +513,7 @@ pub async fn generate_page_nfo( if !should_run { return Ok(()); } - let single_page = video_model.single_page.ok_or(anyhow!("single_page is null"))?; + let single_page = video_model.single_page.context("single_page is null")?; let nfo_serializer = if single_page { NFOSerializer(ModelWrapper::Video(video_model), NFOMode::MOVIE) } else {