refactor: 引入 enum_dispatch 静态分发,提升性能 (#232)
This commit is contained in:
@@ -9,7 +9,7 @@ use sea_orm::sea_query::{OnConflict, SimpleExpr};
|
||||
use sea_orm::ActiveValue::Set;
|
||||
use sea_orm::{DatabaseConnection, Unchanged};
|
||||
|
||||
use crate::adapter::{VideoListModel, _ActiveModel};
|
||||
use crate::adapter::{VideoListModel, VideoListModelEnum, _ActiveModel};
|
||||
use crate::bilibili::{BiliClient, Collection, CollectionItem, CollectionType, VideoInfo};
|
||||
|
||||
impl VideoListModel for collection::Model {
|
||||
@@ -98,10 +98,7 @@ pub(super) async fn collection_from<'a>(
|
||||
path: &Path,
|
||||
bili_client: &'a BiliClient,
|
||||
connection: &DatabaseConnection,
|
||||
) -> Result<(
|
||||
Box<dyn VideoListModel>,
|
||||
Pin<Box<dyn Stream<Item = Result<VideoInfo>> + 'a>>,
|
||||
)> {
|
||||
) -> Result<(VideoListModelEnum, Pin<Box<dyn Stream<Item = Result<VideoInfo>> + 'a>>)> {
|
||||
let collection = Collection::new(bili_client, collection_item);
|
||||
let collection_info = collection.get_info().await?;
|
||||
collection::Entity::insert(collection::ActiveModel {
|
||||
@@ -124,18 +121,17 @@ pub(super) async fn collection_from<'a>(
|
||||
.exec(connection)
|
||||
.await?;
|
||||
Ok((
|
||||
Box::new(
|
||||
collection::Entity::find()
|
||||
.filter(
|
||||
collection::Column::SId
|
||||
.eq(collection_item.sid.clone())
|
||||
.and(collection::Column::MId.eq(collection_item.mid.clone()))
|
||||
.and(collection::Column::Type.eq(Into::<i32>::into(collection_item.collection_type.clone()))),
|
||||
)
|
||||
.one(connection)
|
||||
.await?
|
||||
.context("collection not found")?,
|
||||
),
|
||||
collection::Entity::find()
|
||||
.filter(
|
||||
collection::Column::SId
|
||||
.eq(collection_item.sid.clone())
|
||||
.and(collection::Column::MId.eq(collection_item.mid.clone()))
|
||||
.and(collection::Column::Type.eq(Into::<i32>::into(collection_item.collection_type.clone()))),
|
||||
)
|
||||
.one(connection)
|
||||
.await?
|
||||
.context("collection not found")?
|
||||
.into(),
|
||||
Box::pin(collection.into_video_stream()),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use sea_orm::sea_query::{OnConflict, SimpleExpr};
|
||||
use sea_orm::ActiveValue::Set;
|
||||
use sea_orm::{DatabaseConnection, Unchanged};
|
||||
|
||||
use crate::adapter::{VideoListModel, _ActiveModel};
|
||||
use crate::adapter::{VideoListModel, VideoListModelEnum, _ActiveModel};
|
||||
use crate::bilibili::{BiliClient, FavoriteList, VideoInfo};
|
||||
|
||||
impl VideoListModel for favorite::Model {
|
||||
@@ -70,10 +70,7 @@ pub(super) async fn favorite_from<'a>(
|
||||
path: &Path,
|
||||
bili_client: &'a BiliClient,
|
||||
connection: &DatabaseConnection,
|
||||
) -> Result<(
|
||||
Box<dyn VideoListModel>,
|
||||
Pin<Box<dyn Stream<Item = Result<VideoInfo>> + 'a>>,
|
||||
)> {
|
||||
) -> Result<(VideoListModelEnum, Pin<Box<dyn Stream<Item = Result<VideoInfo>> + 'a>>)> {
|
||||
let favorite = FavoriteList::new(bili_client, fid.to_owned());
|
||||
let favorite_info = favorite.get_info().await?;
|
||||
favorite::Entity::insert(favorite::ActiveModel {
|
||||
@@ -90,13 +87,12 @@ pub(super) async fn favorite_from<'a>(
|
||||
.exec(connection)
|
||||
.await?;
|
||||
Ok((
|
||||
Box::new(
|
||||
favorite::Entity::find()
|
||||
.filter(favorite::Column::FId.eq(favorite_info.id))
|
||||
.one(connection)
|
||||
.await?
|
||||
.context("favorite not found")?,
|
||||
),
|
||||
favorite::Entity::find()
|
||||
.filter(favorite::Column::FId.eq(favorite_info.id))
|
||||
.one(connection)
|
||||
.await?
|
||||
.context("favorite not found")?
|
||||
.into(),
|
||||
Box::pin(favorite.into_video_stream()),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -7,17 +7,33 @@ use std::path::Path;
|
||||
use std::pin::Pin;
|
||||
|
||||
use anyhow::Result;
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use futures::Stream;
|
||||
use sea_orm::entity::prelude::*;
|
||||
use sea_orm::sea_query::SimpleExpr;
|
||||
use sea_orm::DatabaseConnection;
|
||||
|
||||
#[rustfmt::skip]
|
||||
use bili_sync_entity::collection::Model as Collection;
|
||||
use bili_sync_entity::favorite::Model as Favorite;
|
||||
use bili_sync_entity::submission::Model as Submission;
|
||||
use bili_sync_entity::watch_later::Model as WatchLater;
|
||||
|
||||
use crate::adapter::collection::collection_from;
|
||||
use crate::adapter::favorite::favorite_from;
|
||||
use crate::adapter::submission::submission_from;
|
||||
use crate::adapter::watch_later::watch_later_from;
|
||||
use crate::bilibili::{BiliClient, CollectionItem, VideoInfo};
|
||||
|
||||
#[enum_dispatch]
|
||||
pub enum VideoListModelEnum {
|
||||
Favorite,
|
||||
Collection,
|
||||
Submission,
|
||||
WatchLater,
|
||||
}
|
||||
|
||||
#[enum_dispatch(VideoListModelEnum)]
|
||||
pub trait VideoListModel {
|
||||
/// 获取特定视频列表的筛选条件
|
||||
fn filter_expr(&self) -> SimpleExpr;
|
||||
@@ -67,10 +83,7 @@ pub async fn video_list_from<'a>(
|
||||
path: &Path,
|
||||
bili_client: &'a BiliClient,
|
||||
connection: &DatabaseConnection,
|
||||
) -> Result<(
|
||||
Box<dyn VideoListModel>,
|
||||
Pin<Box<dyn Stream<Item = Result<VideoInfo>> + 'a>>,
|
||||
)> {
|
||||
) -> Result<(VideoListModelEnum, Pin<Box<dyn Stream<Item = Result<VideoInfo>> + 'a>>)> {
|
||||
match args {
|
||||
Args::Favorite { fid } => favorite_from(fid, path, bili_client, connection).await,
|
||||
Args::Collection { collection_item } => collection_from(collection_item, path, bili_client, connection).await,
|
||||
|
||||
@@ -9,7 +9,7 @@ use sea_orm::sea_query::{OnConflict, SimpleExpr};
|
||||
use sea_orm::ActiveValue::Set;
|
||||
use sea_orm::{DatabaseConnection, Unchanged};
|
||||
|
||||
use crate::adapter::{VideoListModel, _ActiveModel};
|
||||
use crate::adapter::{VideoListModel, VideoListModelEnum, _ActiveModel};
|
||||
use crate::bilibili::{BiliClient, Submission, VideoInfo};
|
||||
|
||||
impl VideoListModel for submission::Model {
|
||||
@@ -82,10 +82,7 @@ pub(super) async fn submission_from<'a>(
|
||||
path: &Path,
|
||||
bili_client: &'a BiliClient,
|
||||
connection: &DatabaseConnection,
|
||||
) -> Result<(
|
||||
Box<dyn VideoListModel>,
|
||||
Pin<Box<dyn Stream<Item = Result<VideoInfo>> + 'a>>,
|
||||
)> {
|
||||
) -> Result<(VideoListModelEnum, Pin<Box<dyn Stream<Item = Result<VideoInfo>> + 'a>>)> {
|
||||
let submission = Submission::new(bili_client, upper_id.to_owned());
|
||||
let upper = submission.get_info().await?;
|
||||
submission::Entity::insert(submission::ActiveModel {
|
||||
@@ -102,13 +99,12 @@ pub(super) async fn submission_from<'a>(
|
||||
.exec(connection)
|
||||
.await?;
|
||||
Ok((
|
||||
Box::new(
|
||||
submission::Entity::find()
|
||||
.filter(submission::Column::UpperId.eq(upper.mid))
|
||||
.one(connection)
|
||||
.await?
|
||||
.context("submission not found")?,
|
||||
),
|
||||
submission::Entity::find()
|
||||
.filter(submission::Column::UpperId.eq(upper.mid))
|
||||
.one(connection)
|
||||
.await?
|
||||
.context("submission not found")?
|
||||
.into(),
|
||||
Box::pin(submission.into_video_stream()),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ use sea_orm::sea_query::{OnConflict, SimpleExpr};
|
||||
use sea_orm::ActiveValue::Set;
|
||||
use sea_orm::{DatabaseConnection, Unchanged};
|
||||
|
||||
use crate::adapter::{VideoListModel, _ActiveModel};
|
||||
use crate::adapter::{VideoListModel, VideoListModelEnum, _ActiveModel};
|
||||
use crate::bilibili::{BiliClient, VideoInfo, WatchLater};
|
||||
|
||||
impl VideoListModel for watch_later::Model {
|
||||
@@ -66,10 +66,7 @@ pub(super) async fn watch_later_from<'a>(
|
||||
path: &Path,
|
||||
bili_client: &'a BiliClient,
|
||||
connection: &DatabaseConnection,
|
||||
) -> Result<(
|
||||
Box<dyn VideoListModel>,
|
||||
Pin<Box<dyn Stream<Item = Result<VideoInfo>> + 'a>>,
|
||||
)> {
|
||||
) -> Result<(VideoListModelEnum, Pin<Box<dyn Stream<Item = Result<VideoInfo>> + 'a>>)> {
|
||||
let watch_later = WatchLater::new(bili_client);
|
||||
watch_later::Entity::insert(watch_later::ActiveModel {
|
||||
id: Set(1),
|
||||
@@ -84,13 +81,12 @@ pub(super) async fn watch_later_from<'a>(
|
||||
.exec(connection)
|
||||
.await?;
|
||||
Ok((
|
||||
Box::new(
|
||||
watch_later::Entity::find()
|
||||
.filter(watch_later::Column::Id.eq(1))
|
||||
.one(connection)
|
||||
.await?
|
||||
.context("watch_later not found")?,
|
||||
),
|
||||
watch_later::Entity::find()
|
||||
.filter(watch_later::Column::Id.eq(1))
|
||||
.one(connection)
|
||||
.await?
|
||||
.context("watch_later not found")?
|
||||
.into(),
|
||||
Box::pin(watch_later.into_video_stream()),
|
||||
))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user