rust-wechat-core 0.1.3

wechat api core
Documentation
use std::borrow::Borrow;
use crate::{ServerError, WechatError};
#[cfg(feature = "multipart")]
use reqwest::multipart;
use reqwest::{IntoUrl, Url};
use serde::de::DeserializeOwned;
use serde::{Deserialize, Serialize};

pub trait ClientTrait {
    fn access_token(&self) -> impl Future<Output = crate::Result<String>> + Send;
    fn refresh_access_token(&mut self) -> impl Future<Output = crate::Result<()>> + Send;
    fn http_client(&self) -> &reqwest::Client;
    fn url_with_query<I, K, V>(&self, url: &str, queries: I) -> crate::Result<Url>
    where
        I: IntoIterator,
        I::Item: Borrow<(K, V)>,
        K: AsRef<str>,
        V: AsRef<str>,
    {
        Ok(
            Url::parse_with_params(url, queries)
                .map_err(|err| WechatError::CommonError(err.to_string()))?,
        )
    }
    
    fn authorized_url(&self, url: &str) -> impl Future<Output = crate::Result<Url>> + Send
    where
        Self: Sync,
    {
        async {
            let access_token = self.access_token().await?;
            self.url_with_query(url, &[("access_token", access_token)])
        }
    }

    fn get_empty<R: DeserializeOwned, U: IntoUrl + Send, >(
        &self,
        url: U,
    ) -> impl Future<Output = crate::Result<R>> + Send
    where
        Self: Sync,
    {
        async {
            Ok(self
                .http_client()
                .get(url)
                .send()
                .await?
                .json::<R>()
                .await?)
        }
    }

    fn get<R: DeserializeOwned, U: IntoUrl + Send, T: Serialize + ?Sized + Sync>(
        &self,
        url: U,
        query: &T,
    ) -> impl Future<Output = crate::Result<R>> + Send
    where
        Self: Sync,
    {
        async {
            Ok(self
                .http_client()
                .get(url)
                .query(query)
                .send()
                .await?
                .json::<R>()
                .await?)
        }
    }

    fn post_empty<R: DeserializeOwned, U: IntoUrl + Send>(
        &self,
        url: U,
    ) -> impl Future<Output = crate::Result<R>> + Send
    where
        Self: Sync,
    {
        async {
            Ok(self
                .http_client()
                .post(url)
                .send()
                .await?
                .json::<R>()
                .await?)
        }
    }

    fn post<R: DeserializeOwned, U: IntoUrl + Send, T: Serialize + ?Sized + Sync>(
        &self,
        url: U,
        data: &T,
    ) -> impl Future<Output = crate::Result<R>> + Send
    where
        Self: Sync,
    {
        async {
            Ok(self
                .http_client()
                .post(url)
                .form(data)
                .send()
                .await?
                .json::<R>()
                .await?)
        }
    }

    #[cfg(feature = "multipart")]
    fn upload<R: DeserializeOwned, U: IntoUrl + Send>(
        &self,
        url: U,
        multipart: multipart::Form,
    ) -> impl Future<Output = crate::Result<R>> + Send
    where
        Self: Sync,
    {
        async {
            Ok(self
                .http_client()
                .post(url)
                .multipart(multipart)
                .send()
                .await?
                .json::<R>()
                .await?)
        }
    }

    #[cfg(feature = "multipart")]
    fn upload_with<R: DeserializeOwned, U: IntoUrl + Send, T: Serialize + ?Sized + Sync>(
        &self,
        url: U,
        data: &T,
        multipart: multipart::Form,
    ) -> impl Future<Output = crate::Result<R>> + Send
    where
        Self: Sync,
    {
        async {
            Ok(self
                .http_client()
                .post(url)
                .form(data)
                .multipart(multipart)
                .send()
                .await?
                .json::<R>()
                .await?)
        }
    }

    fn json<R: DeserializeOwned, U: IntoUrl + Send, T: Serialize + ?Sized + Sync>(
        &self,
        url: U,
        data: &T,
    ) -> impl Future<Output = crate::Result<R>> + Send
    where
        Self: Sync,
    {
        async {
            Ok(self
                .http_client()
                .post(url)
                .json(data)
                .send()
                .await?
                .json::<R>()
                .await?)
        }
    }
    
    fn download<U: IntoUrl + Send, T: Serialize + ?Sized + Sync>(
        &self,
        url: U,
        query: &T,
    ) -> impl Future<Output = crate::Result<Vec<u8>>> + Send
    where
        Self: Sync,
    {
        async {
            let response = self
                .http_client()
                .get(url)
                .query(query)
                .send()
                .await?;
            
            if  response.status() == 200 {
                Ok(response.bytes().await?.to_vec())
            } else {
                let res: ServerError = response.json().await?;
                Err(WechatError::ServerError(res))
            }
        }
    }
}