From 7a61077d80d986c5b29bddc25a30e1c2230d56d9 Mon Sep 17 00:00:00 2001 From: YoursFunny Date: Mon, 21 Sep 2026 17:19:26 +0800 Subject: [PATCH] refactor(pixiv): keep the artwork type as the API's string TypeModel's Illust and Manga variants existed only so serde would accept those values -- both call sites ask a single question (is this ugoira?), so the field is a String and the check is a comparison. Same for a type the API adds later: it no longer fails the whole parse. --- crates/x-media/src/site/pixiv/api.rs | 4 ++-- crates/x-media/src/site/pixiv/interface.rs | 4 ++-- crates/x-media/src/site/pixiv/model.rs | 15 ++++----------- 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/crates/x-media/src/site/pixiv/api.rs b/crates/x-media/src/site/pixiv/api.rs index b222476..e777597 100644 --- a/crates/x-media/src/site/pixiv/api.rs +++ b/crates/x-media/src/site/pixiv/api.rs @@ -4,7 +4,7 @@ //! `app-api.pixiv.net`, deserialized with the kept `model.rs` types. use super::interface::Illustration; -use super::model::{IllustrationModel, TypeModel, UgoiraMetadataModel}; +use super::model::{IllustrationModel, UgoiraMetadataModel}; use crate::media::Media; use crate::site::FetchError; use std::env; @@ -139,7 +139,7 @@ impl PixivAPI { pub async fn fetch(&self, illust_id: u64) -> Result { let model = self.illust_detail(illust_id).await?; let mut illustration = Illustration::from_model(&model); - if matches!(&model.r#type, TypeModel::Ugoira) { + if model.r#type == "ugoira" { // Real ugoira support: download the frame zip and encode an MP4. // Without ffmpeg the post stays unsupported (empty media, like // Python) — but a *failed* download/encode is reported instead: diff --git a/crates/x-media/src/site/pixiv/interface.rs b/crates/x-media/src/site/pixiv/interface.rs index 01f3bec..4d6edd0 100644 --- a/crates/x-media/src/site/pixiv/interface.rs +++ b/crates/x-media/src/site/pixiv/interface.rs @@ -1,4 +1,4 @@ -use super::model::{IllustrationModel, TypeModel}; +use super::model::IllustrationModel; use crate::media::Media; use crate::site::{FetchError, Fetched, PixivError, Site, SiteFuture}; use html_escape::{encode_double_quoted_attribute, encode_text}; @@ -225,7 +225,7 @@ impl Illustration { tags.insert(0, "AI".to_string()); } let mut media = vec![]; - if matches!(&model.r#type, TypeModel::Ugoira) { + if model.r#type == "ugoira" { // No static images for ugoira; the fetch path encodes an MP4 via // ffmpeg and appends it as a Video item (api.rs). This fallback // keeps media empty when encoding fails or ffmpeg is missing. diff --git a/crates/x-media/src/site/pixiv/model.rs b/crates/x-media/src/site/pixiv/model.rs index f6c8103..e7465ff 100644 --- a/crates/x-media/src/site/pixiv/model.rs +++ b/crates/x-media/src/site/pixiv/model.rs @@ -10,7 +10,10 @@ pub struct IllustrationModel { /// works (`
`, ``, sometimes `

`), empty for many. #[serde(default)] pub caption: String, - pub r#type: TypeModel, + /// `"illust"` / `"manga"` / `"ugoira"`; only ugoira changes how the + /// artwork is fetched (a zip of frames to encode), so the rest is kept as + /// the string the API sent rather than as variants nothing matches. + pub r#type: String, pub image_urls: ImageUrlsModel, pub user: UserInfoModel, pub tags: Vec, @@ -22,16 +25,6 @@ pub struct IllustrationModel { pub meta_pages: Vec, } -#[derive(Deserialize, Debug)] -pub enum TypeModel { - #[serde(rename = "illust")] - Illust, - #[serde(rename = "manga")] - Manga, - #[serde(rename = "ugoira")] - Ugoira, -} - #[derive(Deserialize, Debug)] pub struct UserInfoModel { pub id: u64,