use serde::{Deserialize, Serialize};
use crate::{session::SessionStore, request::{RequestType}, errors::LabraError, WechatCommonResponse, WechatMpClient, LabradorResult};
use crate::wechat::mp::method::{MpMenuMethod, WechatMpMethod};
#[derive(Debug, Clone)]
pub struct WechatMpMenu<'a, T: SessionStore> {
client: &'a WechatMpClient<T>,
}
#[allow(unused)]
impl<'a, T: SessionStore> WechatMpMenu<'a, T> {
#[inline]
pub fn new(client: &WechatMpClient<T>) -> WechatMpMenu<T> {
WechatMpMenu {
client,
}
}
pub async fn create_menu<D: Serialize>(&self, data: D) -> LabradorResult<WechatCommonResponse> {
self.client.post(WechatMpMethod::Menu(MpMenuMethod::Create), vec![], data, RequestType::Json).await?.json::<WechatCommonResponse>()
}
pub async fn create_custom_menu(&self, buttons: MenuButtonsRequest) -> LabradorResult<WechatCommonResponse> {
self.create_menu::<MenuButtonsRequest>(buttons).await
}
pub async fn get_current_selfmenu_info(&self) -> LabradorResult<SelfMenuInfoResponse> {
let v = self.client.get(WechatMpMethod::Menu(MpMenuMethod::GetCurrentMenuInfo), vec![], RequestType::Json).await?.json::<serde_json::Value>()?;
let mut result = WechatCommonResponse::from_value(v.clone())?;
if result.is_success() {
Ok(serde_json::from_value::<SelfMenuInfoResponse>(v)?)
} else {
Err(LabraError::ClientError {errcode: result.errcode.to_owned().unwrap_or_default().to_string(), errmsg: result.errmsg.to_owned().unwrap_or_default()})
}
}
pub async fn get_menu(&self) -> LabradorResult<MenuButtonResponse> {
let v = self.client.get(WechatMpMethod::Menu(MpMenuMethod::Get), vec![], RequestType::Json).await?.json::<serde_json::Value>()?;
let mut result = WechatCommonResponse::from_value(v.clone())?;
if result.is_success() {
Ok(serde_json::from_value::<MenuButtonResponse>(v)?)
} else {
Err(LabraError::ClientError {errcode: result.errcode.to_owned().unwrap_or_default().to_string(), errmsg: result.errmsg.to_owned().unwrap_or_default()})
}
}
pub async fn delete_menu(&self) -> LabradorResult<MenuButtonResponse> {
let v = self.client.get(WechatMpMethod::Menu(MpMenuMethod::Delete), vec![], RequestType::Json).await?.json::<serde_json::Value>()?;
let mut result = WechatCommonResponse::from_value(v.clone())?;
if result.is_success() {
Ok(serde_json::from_value::<MenuButtonResponse>(v)?)
} else {
Err(LabraError::ClientError {errcode: result.errcode.to_owned().unwrap_or_default().to_string(), errmsg: result.errmsg.to_owned().unwrap_or_default()})
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MenuButtonsRequest {
pub button: Vec<MenuButton>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MenuButton {
#[serde(rename = "type")]
pub button_type: String,
pub name: String,
pub url: Option<String>,
pub key: Option<String>,
pub media_id: Option<String>,
pub appid: Option<String>,
pub pagepath: Option<String>,
pub sub_button: Option<Vec<MenuButton>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SelfMenuInfoResponse {
pub is_menu_open: Option<u8>,
pub selfmenu_info: Option<SelfMenuInfo>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SelfMenuInfo {
pub button: Option<Vec<SelfMenuButton>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SelfMenuButton {
#[serde(rename = "type")]
pub button_type: Option<String>,
pub name: String,
pub url: Option<String>,
pub key: Option<String>,
pub media_id: Option<String>,
pub appid: Option<String>,
pub pagepath: Option<String>,
pub news_info: Option<SelfMenuNewsButton>,
pub sub_button: Option<SelfMenuSubButton>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SelfMenuSubButton {
pub list: Option<Vec<SelfMenuButton>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SelfMenuNewsButton {
pub list: Option<Vec<SelfMenuNewsInfo>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SelfMenuNewsInfo {
pub title: Option<String>,
pub digest: Option<String>,
pub author: Option<String>,
pub show_cover: Option<u8>,
pub cover_url: Option<String>,
pub content_url: Option<String>,
pub source_url: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MenuButtonResponse {
pub menu: Option<MenuButtonsInner>,
pub conditionalmenu: Option<MenuButtonsInner>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MenuButtonsInner {
pub button: Option<Vec<MenuButton>>,
pub menuid: Option<u32>,
}