Skip to main content

wx_rust_common/util/http/
media_upload_request_executor.rs

1//! 媒体上传请求执行器。
2//!
3//! 对应 Java `me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor`
4//! (及 Apache/OkHttp/Jodd/HttpComponents 四后端,均为 `PLATFORM_NA`)。
5//! Rust 以 reqwest multipart 统一实现。
6
7use async_trait::async_trait;
8use reqwest::multipart::{Form, Part};
9
10use crate::bean::CommonUploadParam;
11use crate::enums::WxType;
12use crate::error::WxErrorException;
13use crate::util::http::RequestExecutor;
14use crate::util::http::simple_get_request_executor::SimpleGetRequestExecutor;
15
16/// 媒体上传请求执行器。
17///
18/// 使用 multipart/form-data 上传媒体文件(对应 Java `MediaUploadRequestExecutor`)。
19#[derive(Debug, Clone)]
20pub struct MediaUploadRequestExecutor {
21    /// reqwest 客户端
22    client: reqwest::Client,
23}
24
25impl MediaUploadRequestExecutor {
26    /// 构建上传执行器。
27    pub fn new(client: reqwest::Client) -> Self {
28        Self { client }
29    }
30
31    /// 以 multipart 形式上传。
32    ///
33    /// # 参数
34    /// - `uri`:上传接口地址
35    /// - `param`:上传参数(文件参数名 + 数据 + 额外表单字段)
36    /// - `wx_type`:微信模块类型
37    pub async fn upload(
38        &self,
39        uri: &str,
40        param: CommonUploadParam,
41        wx_type: WxType,
42    ) -> Result<String, WxErrorException> {
43        let mut form = Form::new();
44        let file_name = param
45            .data
46            .file_name
47            .clone()
48            .unwrap_or_else(|| "file".to_string());
49        let part = Part::bytes(param.data.content).file_name(file_name);
50        form = form.part(param.name, part);
51        if let Some(fields) = param.form_fields {
52            for (k, v) in fields {
53                form = form.text(k, v);
54            }
55        }
56        let resp = self.client.post(uri).multipart(form).send().await?;
57        let body = resp.text().await?;
58        SimpleGetRequestExecutor::handle_response(wx_type, &body)
59    }
60}
61
62#[async_trait]
63impl RequestExecutor<String, CommonUploadParam> for MediaUploadRequestExecutor {
64    async fn execute(
65        &self,
66        uri: &str,
67        data: CommonUploadParam,
68        wx_type: WxType,
69    ) -> Result<String, WxErrorException> {
70        self.upload(uri, data, wx_type).await
71    }
72}