wechat-minapp 3.2.2

A rust sdk for wechat miniprogram server api
Documentation
use crate::{Result, constants};
use http::{HeaderValue, Method, Request, header};
use serde_json::{Map, Value};
use tracing::debug;
use url::Url;

pub fn parse_url(url: impl Into<String>) -> Result<Url> {
    Ok(Url::parse(&url.into())?)
}

pub fn parse_query(url: impl Into<String>) -> Result<Vec<(String, String)>> {
    let url = parse_url(url)?;
    let paris = url
        .query_pairs()
        .into_iter()
        .map(|s| (s.0.to_string(), s.1.to_string()))
        .collect();
    Ok(paris)
}

pub fn build_request(
    url: &str,
    method: Method,
    headers: Option<Value>,
    query: Option<Value>,
    body: Option<Value>,
) -> Result<Request<Vec<u8>>> {
    let mut req_url = Url::parse(url)?;
    let default_map = Map::new();

    if let Some(value) = query
        && value.is_object()
    {
        debug!("req query value:{:?}", value);

        value
            .as_object()
            .unwrap_or(&default_map)
            .iter()
            .for_each(|item| {
                debug!("req query item:{:?}", item);
                let value_str = match item.1 {
                    Value::String(s) => s,
                    _ => &value.to_string(),
                };
                req_url.query_pairs_mut().append_pair(item.0, value_str);
            });
    }

    let req_builder = Request::builder()
        .uri(req_url.to_string())
        .header(header::USER_AGENT, constants::HTTP_CLIENT_USER_AGENT)
        .method(method);

    let req_builder_with_headers = if let Some(headers_value) = headers
        && headers_value.is_object()
    {
        headers_value
            .as_object()
            .unwrap_or(&default_map)
            .iter()
            .fold(req_builder, |current_builder, (key, value)| {
                let value_str = value.as_str().unwrap_or("");
                let header_value =
                    HeaderValue::from_str(value_str).unwrap_or(HeaderValue::from_static(""));
                current_builder.header(key.as_str(), header_value)
            })
    } else {
        req_builder
    };

    if let Some(value) = body
        && value.is_object()
    {
        debug!("builder body {:?}", &value);
        let body = serde_json::to_vec(&value)?;
        Ok(req_builder_with_headers.body(body)?)
    } else {
        Ok(req_builder_with_headers.body(Vec::new())?)
    }
}