bangumi_api/module/subject/
service.rs

1use anyhow::Result;
2use bytes::Bytes;
3use reqwest::Method;
4
5use crate::{
6    common::model::BangumiClient,
7    module::model::{ImageType, Paged},
8};
9
10use super::model::{
11    DailyCalendarItem, Subject, SubjectBrowseSort, SubjectCategory, SubjectCharacter,
12    SubjectPerson, SubjectSearch, SubjectSubject, SubjectType,
13};
14
15impl BangumiClient {
16    /// 获取每日番剧日历
17    ///
18    /// 获取按星期分类的番剧条目列表,包含每日更新的番剧信息
19    ///
20    /// # 返回
21    /// 成功返回每日日历条目列表,失败返回错误
22    pub async fn get_calendar(&self) -> Result<Vec<DailyCalendarItem>> {
23        let url = format!("{}/calendar", self.base_path);
24
25        let request_builder = self.request_builder(Method::GET, &url);
26
27        let res = self.request_send(request_builder).await?.json().await?;
28
29        Ok(res)
30    }
31
32    /// 搜索番剧条目
33    ///
34    /// 根据搜索条件查询番剧条目,支持分页获取结果
35    ///
36    /// # 参数
37    /// - `limit`: 结果数量上限(可选,限制返回的条目数量)
38    /// - `offset`: 结果偏移量(可选,用于分页,指定从第几条结果开始返回)
39    /// - `payload`: 搜索条件(可选,包含关键词、排序方式、过滤条件等)
40    ///
41    /// # 返回
42    /// 成功返回分页的番剧条目列表,失败返回错误
43    pub async fn search_subjects(
44        &self,
45        limit: Option<u32>,
46        offset: Option<u32>,
47        payload: Option<SubjectSearch>,
48    ) -> Result<Paged<Subject>> {
49        let url = format!("{}/v0/search/subjects", self.base_path);
50        let mut request_builder = self.request_builder(Method::POST, &url);
51
52        if let Some(ref limit) = limit {
53            request_builder = request_builder.query(&[("limit", limit)]);
54        }
55
56        if let Some(ref offset) = offset {
57            request_builder = request_builder.query(&[("offset", offset)]);
58        }
59
60        let request_builder = request_builder.json(&payload);
61
62        let res = self.request_send(request_builder).await?.json().await?;
63
64        Ok(res)
65    }
66
67    /// 获取番剧条目列表
68    ///
69    /// 根据筛选条件获取番剧条目列表,支持按类型、分类、时间等条件筛选
70    ///
71    /// # 参数
72    /// - `r#type`: 条目类型(必需,指定要获取的条目类型,如动画、书籍等)
73    /// - `cat`: 子类别(可选,进一步筛选条目子类别,如动画中的TV、电影等)
74    /// - `series`: 是否为系列作品(可选,筛选系列作品或独立作品)
75    /// - `platform`: 平台(可选,筛选特定平台的条目)
76    /// - `sort`: 排序方式(可选,指定结果排序规则,如按日期、排名排序)
77    /// - `year`: 年份(可选,筛选特定年份的条目)
78    /// - `month`: 月份(可选,筛选特定月份的条目)
79    /// - `limit`: 结果数量上限(可选,限制返回的条目数量)
80    /// - `offset`: 结果偏移量(可选,用于分页,指定从第几条结果开始返回)
81    ///
82    /// # 返回
83    /// 成功返回分页的番剧条目列表,失败返回错误
84    pub async fn get_subjects(
85        &self,
86        r#type: SubjectType,
87        cat: Option<SubjectCategory>,
88        series: Option<bool>,
89        platform: Option<&str>,
90        sort: Option<SubjectBrowseSort>,
91        year: Option<u32>,
92        month: Option<u32>,
93        limit: Option<u32>,
94        offset: Option<u32>,
95    ) -> Result<Paged<Subject>> {
96        let url = format!("{}/v0/subjects", self.base_path);
97        let mut req_builder = self.request_builder(reqwest::Method::GET, &url);
98
99        req_builder = req_builder.query(&[("type", &r#type)]);
100        if let Some(ref param_value) = cat {
101            req_builder = req_builder.query(&[("cat", &param_value)]);
102        }
103        if let Some(ref param_value) = series {
104            req_builder = req_builder.query(&[("series", &param_value)]);
105        }
106        if let Some(ref param_value) = platform {
107            req_builder = req_builder.query(&[("platform", &param_value)]);
108        }
109        if let Some(ref param_value) = sort {
110            req_builder = req_builder.query(&[("sort", &param_value)]);
111        }
112        if let Some(ref param_value) = year {
113            req_builder = req_builder.query(&[("year", &param_value)]);
114        }
115        if let Some(ref param_value) = month {
116            req_builder = req_builder.query(&[("month", &param_value)]);
117        }
118        if let Some(ref param_value) = limit {
119            req_builder = req_builder.query(&[("limit", &param_value)]);
120        }
121        if let Some(ref param_value) = offset {
122            req_builder = req_builder.query(&[("offset", &param_value)]);
123        }
124
125        let res = self.request_send(req_builder).await?.json().await?;
126        Ok(res)
127    }
128
129    /// 获取单个番剧条目详情
130    ///
131    /// 根据条目ID获取指定番剧条目的详细信息,包括名称、简介、评分等
132    ///
133    /// # 参数
134    /// - `subject_id`: 条目ID(必需,指定要获取详情的番剧条目)
135    ///
136    /// # 返回
137    /// 成功返回番剧条目详情,失败返回错误
138    pub async fn get_subject(&self, subject_id: u32) -> Result<Subject> {
139        let url = format!("{}/v0/subjects/{subject_id}", self.base_path);
140
141        let request_builder = self.request_builder(Method::GET, &url);
142
143        let res = self.request_send(request_builder).await?.json().await?;
144
145        Ok(res)
146    }
147
148    /// 获取番剧条目图片
149    ///
150    /// 根据条目ID和图片类型获取指定番剧条目的图片数据
151    ///
152    /// # 参数
153    /// - `subject_id`: 条目ID(必需,指定要获取图片的番剧条目)
154    /// - `r#type`: 图片类型(必需,指定要获取的图片类型)
155    ///
156    /// # 返回
157    /// 成功返回图片二进制数据,失败返回错误
158    pub async fn get_subject_image(&self, subject_id: u32, r#type: ImageType) -> Result<Bytes> {
159        let url = format!("{}/v0/subjects/{subject_id}/image", self.base_path);
160
161        let mut request_builder = self.request_builder(Method::GET, &url);
162
163        request_builder = request_builder.query(&[("type", &r#type)]);
164
165        let res = self.request_send(request_builder).await?.bytes().await?;
166
167        Ok(res)
168    }
169
170    /// 获取番剧条目相关人物
171    ///
172    /// 根据条目ID获取与该番剧条目相关的人物信息,如制作人员、声优等
173    ///
174    /// # 参数
175    /// - `subject_id`: 条目ID(必需,指定要获取相关人物的番剧条目)
176    ///
177    /// # 返回
178    /// 成功返回相关人物列表,失败返回错误
179    pub async fn get_subject_persons(&self, subject_id: u32) -> Result<Vec<SubjectPerson>> {
180        let url = format!("{}/v0/subjects/{subject_id}/persons", self.base_path);
181
182        let request_builder = self.request_builder(Method::GET, &url);
183
184        let res = self.request_send(request_builder).await?.json().await?;
185
186        Ok(res)
187    }
188
189    /// 获取番剧条目相关角色
190    ///
191    /// 根据条目ID获取与该番剧条目相关的角色信息,包括角色名称、简介及配音演员等
192    ///
193    /// # 参数
194    /// - `subject_id`: 条目ID(必需,指定要获取相关角色的番剧条目)
195    ///
196    /// # 返回
197    /// 成功返回相关角色列表,失败返回错误
198    pub async fn get_subject_characters(&self, subject_id: u32) -> Result<Vec<SubjectCharacter>> {
199        let url = format!("{}/v0/subjects/{subject_id}/characters", self.base_path);
200
201        let request_builder = self.request_builder(Method::GET, &url);
202
203        let res = self.request_send(request_builder).await?.json().await?;
204
205        Ok(res)
206    }
207
208    /// 获取番剧条目相关其他条目
209    ///
210    /// 根据条目ID获取与该番剧条目相关的其他番剧条目,如系列作品、衍生作品等
211    ///
212    /// # 参数
213    /// - `subject_id`: 条目ID(必需,指定要获取相关条目的番剧条目)
214    ///
215    /// # 返回
216    /// 成功返回相关条目列表,失败返回错误
217    pub async fn get_subject_subjects(&self, subject_id: u32) -> Result<Vec<SubjectSubject>> {
218        let url = format!("{}/v0/subjects/{subject_id}/subjects", self.base_path);
219
220        let request_builder = self.request_builder(Method::GET, &url);
221
222        let res = self.request_send(request_builder).await?.json().await?;
223
224        Ok(res)
225    }
226}