use serde::{Deserialize, Serialize};
use crate::{
prelude::{WalleError, WalleResult},
util::Value,
};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct Resp {
pub status: String,
pub retcode: u32,
pub data: Value,
pub message: String,
}
impl<T> From<T> for Resp
where
T: Into<Value>,
{
fn from(data: T) -> Self {
Self {
status: "ok".to_string(),
retcode: 0,
data: data.into(),
message: "".to_string(),
}
}
}
#[derive(Clone)]
pub struct RespError {
pub retcode: u32,
pub message: String,
}
impl std::fmt::Debug for RespError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "RespError[{}]: {}", self.retcode, self.message)
}
}
impl From<RespError> for Resp {
fn from(error: RespError) -> Self {
Self {
status: "failed".to_string(),
retcode: error.retcode,
data: Value::Null,
message: error.message,
}
}
}
impl Resp {
pub fn as_result(self) -> WalleResult<Value> {
if self.retcode != 0 {
Err(WalleError::RespError(RespError {
retcode: self.retcode,
message: self.message,
}))
} else {
Ok(self.data)
}
}
pub fn as_resul_downcast<T: TryFrom<Value, Error = WalleError>>(
self,
) -> WalleResult<T> {
self.as_result().and_then(|v| v.try_into())
}
}
pub mod resp_error {
use super::RespError;
#[macro_export]
macro_rules! error_type {
($name: ident, $retcode: expr, $message: expr) => {
pub fn $name<T: std::fmt::Display>(msg: T) -> RespError {
RespError {
retcode: $retcode,
message: {
let mut message = String::from($message);
let msg = msg.to_string();
if msg != String::default() {
message.push(':');
message.push_str(&msg);
}
message
},
}
}
};
}
error_type!(bad_request, 10001, "无效的动作请求");
error_type!(unsupported_action, 10002, "不支持的动作");
error_type!(bad_param, 10003, "无效的动作请求参数");
error_type!(unsupported_param, 10004, "不支持的动作请求参数");
error_type!(unsupported_segment, 10005, "不支持的消息段类型");
error_type!(bad_segment_data, 10006, "无效的消息段参数");
error_type!(unsupported_segment_data, 10007, "不支持的消息段参数");
error_type!(bad_handler, 20001, "动作处理器实现错误");
error_type!(internal_handler, 20002, "动作处理器运行时抛出异常");
error_type!(database_error, 31000, "数据库错误");
error_type!(filesystem_error, 32000, "文件系统错误");
error_type!(network_error, 33000, "网络错误");
error_type!(platform_error, 34000, "机器人平台错误");
error_type!(tired, 36000, "I Am Tired!");
}