refactor: 使用 context 代替 ok_or 和 ok_or_else

This commit is contained in:
amtoaer
2025-01-21 18:06:54 +08:00
parent 0f25923c52
commit 1a32e38dc3
10 changed files with 44 additions and 53 deletions

View File

@@ -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()),
))

View File

@@ -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()),
))

View File

@@ -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()),
))

View File

@@ -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()),
))

View File

@@ -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<Stream>, Vec<Stream>) =
@@ -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)

View File

@@ -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<WbiImg> {
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
}
}

View File

@@ -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::<serde_json::Value>()
.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<Self> {
@@ -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<String> {
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())
}

View File

@@ -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)
}
}

View File

@@ -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)
}

View File

@@ -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<video::ActiveModel> {
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<Pin<Box<dyn Future<Output = Result<()>>>>> = 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 {