use std::sync::Arc;
use serde::de::DeserializeOwned;
use serde::Serialize;
use crate::client::WechatClient;
use crate::error::WechatError;
use crate::token::TokenManager;
#[derive(Clone)]
pub struct WechatContext {
pub(crate) client: Arc<WechatClient>,
pub(crate) token_manager: Arc<TokenManager>,
}
impl std::fmt::Debug for WechatContext {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("WechatContext")
.field("client", &"WechatClient { .. }")
.field("token_manager", &"TokenManager { .. }")
.finish()
}
}
impl WechatContext {
pub fn new(client: Arc<WechatClient>, token_manager: Arc<TokenManager>) -> Self {
Self {
client,
token_manager,
}
}
pub fn client(&self) -> &WechatClient {
&self.client
}
pub fn token_manager(&self) -> &TokenManager {
&self.token_manager
}
pub(crate) async fn authed_get<T: DeserializeOwned>(
&self,
path: &str,
extra_query: &[(&str, &str)],
) -> Result<T, WechatError> {
let token = self.token_manager.get_token().await?;
let authed_path = WechatClient::append_access_token(path, &token);
self.client.get(&authed_path, extra_query).await
}
pub(crate) async fn authed_post<T: DeserializeOwned, B: Serialize>(
&self,
path: &str,
body: &B,
) -> Result<T, WechatError> {
let token = self.token_manager.get_token().await?;
let authed_path = WechatClient::append_access_token(path, &token);
self.client.post(&authed_path, body).await
}
pub(crate) async fn authed_post_raw<B: Serialize>(
&self,
path: &str,
body: &B,
) -> Result<reqwest::Response, WechatError> {
let token = self.token_manager.get_token().await?;
let authed_path = WechatClient::append_access_token(path, &token);
let url = format!("{}{}", self.client.base_url(), &authed_path);
let request = self.client.http().post(&url).json(body).build()?;
Ok(self.client.send_request(request).await?)
}
}
pub trait WechatApi: Send + Sync {
fn context(&self) -> &WechatContext;
fn api_name(&self) -> &'static str {
"unknown"
}
}