bangumi_api/module/character/
service.rs

1use anyhow::Result;
2use bytes::Bytes;
3use reqwest::Method;
4
5use crate::{
6    common::model::BangumiClient,
7    module::model::{Paged, SimpleImageType},
8};
9
10use super::model::{Character, CharacterPerson, CharacterSearch, CharacterSubject};
11
12impl BangumiClient {
13    /// 搜索角色
14    ///
15    /// 执行角色搜索请求,支持分页和过滤条件
16    ///
17    /// # 参数
18    /// - `limit`: 每页返回的结果数量
19    /// - `offset`: 结果偏移量,用于分页
20    /// - `payload`: 搜索条件,包含关键词和过滤选项
21    ///
22    /// # 返回
23    /// 返回一个包含角色列表的分页结果
24    pub async fn search_characters(
25        &self,
26        limit: Option<u32>,
27        offset: Option<u32>,
28        payload: Option<CharacterSearch>,
29    ) -> Result<Paged<Character>> {
30        let url = format!("{}/v0/search/characters", self.base_path);
31
32        let mut request_builder = self.request_builder(Method::POST, &url);
33
34        // 添加分页参数
35        if let Some(ref param_value) = limit {
36            request_builder = request_builder.query(&[("limit", &param_value)]);
37        }
38        if let Some(ref param_value) = offset {
39            request_builder = request_builder.query(&[("offset", &param_value)]);
40        }
41        // 添加搜索条件
42        request_builder = request_builder.json(&payload);
43
44        // 发送请求并解析响应
45        let res = self.request_send(request_builder).await?.json().await?;
46
47        Ok(res)
48    }
49
50    /// 获取角色详情
51    ///
52    /// 根据角色ID获取角色的详细信息
53    ///
54    /// # 参数
55    /// - `character_id`: 角色ID
56    ///
57    /// # 返回
58    /// 返回包含角色详细信息的结构体
59    pub async fn get_character(&self, character_id: u32) -> Result<Character> {
60        let url = format!("{}/v0/characters/{character_id}", self.base_path);
61
62        let request_builder = self.request_builder(Method::GET, &url);
63
64        // 发送请求并解析响应
65        let res = self.request_send(request_builder).await?.json().await?;
66
67        Ok(res)
68    }
69
70    /// 获取角色图片
71    ///
72    /// 根据角色ID和图片类型获取角色图片的二进制数据
73    ///
74    /// # 参数
75    /// - `character_id`: 角色ID
76    /// - `r#type`: 图片类型
77    ///
78    /// # 返回
79    /// 返回图片的二进制数据
80    pub async fn get_character_image(
81        &self,
82        character_id: u32,
83        r#type: SimpleImageType,
84    ) -> Result<Bytes> {
85        let url = format!("{}/v0/characters/{character_id}/image", self.base_path);
86
87        let mut request_builder = self.request_builder(Method::GET, &url);
88        // 添加图片类型参数
89        request_builder = request_builder.query(&[("type", &r#type)]);
90
91        // 发送请求并获取图片字节数据
92        let res = self.request_send(request_builder).await?.bytes().await?;
93
94        Ok(res)
95    }
96
97    /// 获取角色参与的条目
98    ///
99    /// 根据角色ID获取该角色参与的所有条目信息
100    ///
101    /// # 参数
102    /// - `character_id`: 角色ID
103    ///
104    /// # 返回
105    /// 返回角色参与的条目列表
106    pub async fn get_character_subjects(&self, character_id: u32) -> Result<Vec<CharacterSubject>> {
107        let url = format!("{}/v0/characters/{character_id}/subjects", self.base_path);
108
109        let request_builder = self.request_builder(Method::GET, &url);
110
111        // 发送请求并解析响应
112        let res = self.request_send(request_builder).await?.json().await?;
113
114        Ok(res)
115    }
116
117    /// 获取角色的配音演员或创作者
118    ///
119    /// 根据角色ID获取为该角色配音或创作的人员信息
120    ///
121    /// # 参数
122    /// - `character_id`: 角色ID
123    ///
124    /// # 返回
125    /// 返回角色的配音演员或创作者列表
126    pub async fn get_character_persons(&self, character_id: u32) -> Result<Vec<CharacterPerson>> {
127        let url = format!("{}/v0/characters/{character_id}/persons", self.base_path);
128
129        let request_builder = self.request_builder(Method::GET, &url);
130
131        // 发送请求并解析响应
132        let res = self.request_send(request_builder).await?.json().await?;
133
134        Ok(res)
135    }
136
137    /// 收藏角色
138    ///
139    /// 将指定ID的角色添加到当前用户的收藏列表中
140    ///
141    /// # 参数
142    /// - `character_id`: 角色ID
143    ///
144    /// # 返回
145    /// 操作成功返回Ok(()),失败返回错误
146    pub async fn collect_character(&self, character_id: u32) -> Result<()> {
147        let url = format!("{}/v0/characters/{character_id}/collect", self.base_path);
148
149        let request_builder = self.request_builder(Method::POST, &url);
150
151        // 发送请求并忽略响应内容
152        let _res = self.request_send(request_builder).await?;
153
154        Ok(())
155    }
156
157    /// 取消收藏角色
158    ///
159    /// 从当前用户的收藏列表中移除指定ID的角色
160    ///
161    /// # 参数
162    /// - `character_id`: 角色ID
163    ///
164    /// # 返回
165    /// 操作成功返回Ok(()),失败返回错误
166    pub async fn uncollect_character(&self, character_id: u32) -> Result<()> {
167        let url = format!("{}/v0/characters/{character_id}/collect", self.base_path);
168
169        let request_builder = self.request_builder(Method::DELETE, &url);
170
171        // 发送请求并忽略响应内容
172        let _res = self.request_send(request_builder).await?;
173
174        Ok(())
175    }
176}