diff --git a/src/bilibili/analyzer.rs b/src/bilibili/analyzer.rs index 2b74159..e655021 100644 --- a/src/bilibili/analyzer.rs +++ b/src/bilibili/analyzer.rs @@ -1,10 +1,9 @@ use std::sync::Arc; +use anyhow::{anyhow, bail, Result}; use log::error; use serde::{Deserialize, Serialize}; -use crate::Result; - pub struct PageAnalyzer { info: serde_json::Value, } @@ -161,14 +160,14 @@ impl PageAnalyzer { .as_array() .ok_or_else(|| -> Result { error!("video data is not an array: {:?}", self.info); - Err("invalid video data".into()) + Err(anyhow!("invalid video data")) }) .unwrap_or(&Vec::new()) .iter() { let video_stream_url = video_data["baseUrl"].as_str().unwrap().to_string(); let video_stream_quality = VideoQuality::from_repr(video_data["id"].as_u64().unwrap() as usize) - .ok_or("invalid video stream quality")?; + .ok_or(anyhow!("invalid video stream quality"))?; if (video_stream_quality == VideoQuality::QualityHdr && filter_option.no_hdr) || (video_stream_quality == VideoQuality::QualityDolby && filter_option.no_dolby_video) || (video_stream_quality != VideoQuality::QualityDolby @@ -306,7 +305,7 @@ impl PageAnalyzer { _ => unreachable!(), }); if video_streams.is_empty() { - return Err("no stream found".into()); + bail!("no video stream found"); } Ok(BestStream::VideoAudio { video: video_streams.remove(video_streams.len() - 1), diff --git a/src/bilibili/client.rs b/src/bilibili/client.rs index 9cfbfed..5a5a647 100644 --- a/src/bilibili/client.rs +++ b/src/bilibili/client.rs @@ -1,8 +1,8 @@ +use anyhow::Result; use reqwest::{header, Method}; use crate::bilibili::Credential; use crate::config::CONFIG; -use crate::Result; // 一个对 reqwest::Client 的简单封装,用于 Bilibili 请求 pub struct Client(reqwest::Client); diff --git a/src/bilibili/credential.rs b/src/bilibili/credential.rs index 758a119..6151d7d 100644 --- a/src/bilibili/credential.rs +++ b/src/bilibili/credential.rs @@ -1,5 +1,6 @@ use std::collections::HashSet; +use anyhow::{anyhow, bail, Result}; use cookie::Cookie; use regex::Regex; use reqwest::{header, Method}; @@ -9,7 +10,6 @@ use rsa::{Oaep, RsaPublicKey}; use serde::{Deserialize, Serialize}; use crate::bilibili::Client; -use crate::Result; #[derive(Default, Debug, Clone, Serialize, Deserialize)] pub struct Credential { @@ -43,7 +43,7 @@ impl Credential { .await? .json::() .await?; - res["data"]["refresh"].as_bool().ok_or("check refresh failed".into()) + res["data"]["refresh"].as_bool().ok_or(anyhow!("check refresh failed")) } pub async fn refresh(&mut self, client: &Client) -> Result<()> { @@ -85,8 +85,8 @@ JNrRuoEUXpabUzGB8QIDAQAB .await?; if !res.status().is_success() { return match res.status().as_u16() { - 404 => Err("correspond path is wrong or expired".into()), - _ => Err("get csrf failed".into()), + 404 => Err(anyhow!("correspond path is wrong or expired")), + _ => Err(anyhow!("get csrf failed")), }; } regex_find(r#"
(.+?)
"#, res.text().await?.as_str()) @@ -122,7 +122,7 @@ JNrRuoEUXpabUzGB8QIDAQAB .filter(|x| required_cookies.contains(x.name())) .collect(); if cookies.len() != required_cookies.len() { - return Err("not all required cookies found".into()); + bail!("not all required cookies found"); } for cookie in cookies { match cookie.name() { @@ -134,7 +134,7 @@ JNrRuoEUXpabUzGB8QIDAQAB } let json = res.json::().await?; if !json["data"]["refresh_token"].is_string() { - return Err("refresh_token not found".into()); + bail!("refresh_token not found"); } credential.ac_time_value = json["data"]["refresh_token"].as_str().unwrap().to_string(); Ok(credential) @@ -157,7 +157,7 @@ JNrRuoEUXpabUzGB8QIDAQAB .json::() .await?; if res["code"] != 0 { - return Err(format!("confirm refresh failed: {}", res["message"]).into()); + bail!("confirm refresh failed: {}", res["message"]); } Ok(()) } @@ -168,7 +168,7 @@ fn regex_find(pattern: &str, doc: &str) -> Result { let re = Regex::new(pattern)?; Ok(re .captures(doc) - .ok_or("pattern not match")? + .ok_or(anyhow!("pattern not match"))? .get(1) .unwrap() .as_str() diff --git a/src/bilibili/favorite_list.rs b/src/bilibili/favorite_list.rs index 1299ea1..c63ae35 100644 --- a/src/bilibili/favorite_list.rs +++ b/src/bilibili/favorite_list.rs @@ -1,3 +1,4 @@ +use anyhow::{bail, Result}; use async_stream::stream; use chrono::serde::ts_seconds; use chrono::{DateTime, Utc}; @@ -5,7 +6,6 @@ use futures_core::stream::Stream; use serde_json::Value; use crate::bilibili::BiliClient; -use crate::Result; pub struct FavoriteList<'a> { client: &'a BiliClient, fid: String, @@ -75,7 +75,7 @@ impl<'a> FavoriteList<'a> { .json::() .await?; if res["code"] != 0 { - return Err(format!("get favorite videos failed: {}", res["message"]).into()); + bail!("get favorite videos failed: {}", res["message"]); } Ok(res) } diff --git a/src/bilibili/video.rs b/src/bilibili/video.rs index 370597a..bbbade1 100644 --- a/src/bilibili/video.rs +++ b/src/bilibili/video.rs @@ -1,8 +1,8 @@ +use anyhow::{bail, Result}; use reqwest::Method; use crate::bilibili::analyzer::PageAnalyzer; use crate::bilibili::client::BiliClient; -use crate::Result; static MASK_CODE: u64 = 2251799813685247; static XOR_CODE: u64 = 23442827791579; @@ -89,7 +89,7 @@ impl<'a> Video<'a> { .json::() .await?; if res["code"] != 0 { - return Err(format!("get page analyzer failed: {}", res["message"]).into()); + bail!("get page analyzer failed: {}", res["message"]); } Ok(PageAnalyzer::new(res["data"].take())) } diff --git a/src/config.rs b/src/config.rs index 01e3232..c53e2cb 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,12 +2,12 @@ use std::collections::HashMap; use std::path::Path; use std::sync::Mutex; +use anyhow::{anyhow, Result}; use log::warn; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use crate::bilibili::{Credential, FilterOption}; -use crate::Result; pub static CONFIG: Lazy> = Lazy::new(|| { let config = Config::new(); @@ -75,7 +75,7 @@ impl Config { fn load() -> Result { let config_path = dirs::config_dir() - .ok_or("No config path found")? + .ok_or(anyhow!("No config path found"))? .join("bili-sync") .join("config.toml"); let config_content = std::fs::read_to_string(config_path)?; @@ -84,7 +84,7 @@ impl Config { pub fn save(&self) -> Result<()> { let config_path = dirs::config_dir() - .ok_or("No config path found")? + .ok_or(anyhow!("No config path found"))? .join("bili-sync") .join("config.toml"); if let Some(parent) = config_path.parent() { diff --git a/src/core/command.rs b/src/core/command.rs index b1f2060..ff038f9 100644 --- a/src/core/command.rs +++ b/src/core/command.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::path::{Path, PathBuf}; use std::pin::Pin; +use anyhow::{anyhow, Result}; use dirs::config_dir; use entity::{favorite, page, video}; use filenamify::filenamify; @@ -21,7 +22,6 @@ use super::utils::{unhandled_videos_pages, ModelWrapper, NFOMode, NFOSerializer, use crate::bilibili::{BestStream, BiliClient, FavoriteList, FilterOption, PageInfo, Video}; use crate::core::utils::{create_video_pages, create_videos, exist_labels, filter_videos, handle_favorite_info}; use crate::downloader::Downloader; -use crate::Result; /// 处理某个收藏夹,首先刷新收藏夹信息,然后下载收藏夹中未下载成功的视频 pub async fn process_favorite( @@ -234,7 +234,7 @@ pub async fn dispatch_download_page( &video_model.bvid, page_model.pid, &page_status ); if final_result.is_ok() && page_status.should_run().iter().any(|x| *x) { - final_result = Err("Some page item download failed".into()); + final_result = Err(anyhow!("Some page item download failed")); } } Err(e) => { diff --git a/src/core/status.rs b/src/core/status.rs index d7f12e3..de069e3 100644 --- a/src/core/status.rs +++ b/src/core/status.rs @@ -1,6 +1,6 @@ use core::fmt; -use crate::Result; +use anyhow::Result; static STATUS_MAX_RETRY: u32 = 0b100; static STATUS_OK: u32 = 0b111; @@ -203,6 +203,8 @@ impl From for u32 { #[cfg(test)] mod test { + use anyhow::anyhow; + use super::*; #[test] @@ -210,11 +212,11 @@ mod test { let mut status = Status::new(0); assert_eq!(status.should_run(3), vec![true, true, true]); for count in 1..=3 { - status.update_status(&[Err("".into()), Ok(()), Ok(())]); + status.update_status(&[Err(anyhow!("")), Ok(()), Ok(())]); assert_eq!(status.should_run(3), vec![true, false, false]); assert_eq!(u32::from(status.clone()), 0b111_111_000 + count); } - status.update_status(&[Err("".into()), Ok(()), Ok(())]); + status.update_status(&[Err(anyhow!("")), Ok(()), Ok(())]); assert_eq!(status.should_run(3), vec![false, false, false]); assert_eq!(u32::from(status), 0b111_111_100 | Status::handled()); } diff --git a/src/core/utils.rs b/src/core/utils.rs index d4a50fb..0696b6b 100644 --- a/src/core/utils.rs +++ b/src/core/utils.rs @@ -1,6 +1,7 @@ use std::collections::HashSet; use std::path::Path; +use anyhow::Result; use entity::*; use filenamify::filenamify; use migration::OnConflict; @@ -17,7 +18,6 @@ use tokio::io::AsyncWriteExt; use super::status::Status; use crate::bilibili::{FavoriteListInfo, PageInfo, VideoInfo}; use crate::config::CONFIG; -use crate::Result; pub static TEMPLATE: Lazy = Lazy::new(|| { let mut handlebars = handlebars::Handlebars::new(); diff --git a/src/database.rs b/src/database.rs index 68c7220..e05313a 100644 --- a/src/database.rs +++ b/src/database.rs @@ -1,10 +1,9 @@ +use anyhow::{anyhow, Result}; use migration::{Migrator, MigratorTrait}; use sea_orm::{Database, DatabaseConnection}; use tokio::fs; - -use crate::Result; pub async fn database_connection() -> Result { - let config_dir = dirs::config_dir().ok_or("No config path found")?; + let config_dir = dirs::config_dir().ok_or(anyhow!("No config path found"))?; let target = config_dir.join("bili-sync").join("data.sqlite"); if let Some(parent) = target.parent() { fs::create_dir_all(parent).await?; diff --git a/src/downloader.rs b/src/downloader.rs index fee899a..2493d24 100644 --- a/src/downloader.rs +++ b/src/downloader.rs @@ -1,12 +1,12 @@ use std::path::Path; +use anyhow::{anyhow, Result}; use futures_util::StreamExt; use reqwest::Method; use tokio::fs::{self, File}; use tokio::io; use crate::bilibili::Client; -use crate::Result; pub struct Downloader { client: Client, } @@ -46,8 +46,8 @@ impl Downloader { .await?; if !output.status.success() { return match String::from_utf8(output.stderr) { - Ok(err) => Err(err.into()), - _ => Err("ffmpeg error".into()), + Ok(err) => Err(anyhow!(err)), + _ => Err(anyhow!("ffmpeg error")), }; } let _ = fs::remove_file(video_path).await; diff --git a/src/lib.rs b/src/lib.rs index de27b31..5169314 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,5 @@ -use std::error; - pub mod bilibili; pub mod config; pub mod core; pub mod database; pub mod downloader; - -type Result = std::result::Result>;