一种基于宏和serde_json实现的rust web中统一返回类

news2024/9/23 7:21:23

本人rust萌新,写web碰到了这个,基于ChatGPT和文心一言学了宏,强行把这玩意实现出来了,做个学习记录,如果有更好的方法,勿喷。

先看效果,注意不支持嵌套,且kv映射要用=>(因为它这个只支持用箭头),即在这个宏语法内只支持单层kv,但是你可以传value为HashMap。
对此我曾尝试用#[proc_macro]TokenStream拿到变量名和值的方式实现正常使用花括号和冒号和深层字典,但是太菜了搞不会。
如果能基于我的想法实现出深层kv,欢迎评论区分享。

//第一个变量是msg,后面的全部存入data{key1:...,key2:...}
success!(
   "success",
    "key1"=> vec![1,2,3,4,5],
    "key2" =>"qwer",
    "key3"=>String::from("value")
);

在这里插入图片描述

//第一个变量没了就是默认空msg,后面的全部存入data{key1:...,key2:...}
success!(
 	"key"=>"qwer",
    "key2"=>1324,
);

在这里插入图片描述
fail!同理

rust中实现统一返回类有点麻烦,比如我想返回固定格式

{
	"success":true,
	"msg":"登录成功",
	"data":{
		"id":15,
		"name":"qwer"
	}
}

我目前用的是actix-web,虽然支持直接传入结构体对象作为json返回值,但我有时候想对于data进行灵活的处理,不想建那么多结构体

这里我基于serde_jsonjson!进行进一步封装
这里一个宏里面写两个形式,因为要匹配传入msg和不传入msg的两种情形。最后一个$(,)?是允许最后一个多余的逗号,换行时好看一点

// 随便找个文件放
// 用了#[macro_export]的宏会直接放在crate下

//下面三个库需要在使用下面宏的地方进行use,此处use没用
// use actix_web::web;
// use serde_json::json;
// use std::collections::HashMap;

#[macro_export]
macro_rules! success {
    // 没有msg的情况
    ($($key:expr => $value:expr),* $(,)?) => {
        {
            let mut resp = HashMap::new();
            resp.insert("success", json!(true));
            resp.insert("msg", json!("")); // 提供一个默认的消息
            let mut data:HashMap<String,Value> = HashMap::new();
            $(
                data.insert($key, json!($value));
            )*
            resp.insert("data",json!(data));
            web::Json(json!(resp))
        }
    };
    // 有msg的情况
    ($msg:expr,  $($key:expr => $value:expr),* $(,)?) => {
       {
            let mut resp = HashMap::new();
            resp.insert("success", json!(true));
            resp.insert("msg", json!($msg)); // 提供一个默认的消息
            let mut data:HashMap<String,Value> = HashMap::new();
            $(
                data.insert($key, json!($value));
            )*
            resp.insert("data",json!(data));
            web::Json(json!(resp))
        }
    };
}

#[macro_export]
macro_rules! fail {
    // 没有$msg的情况
    ($($key:expr => $value:expr),* $(,)?) => {
        {
            let mut resp = HashMap::new();
            resp.insert("success", json!(false));
            resp.insert("msg", json!(""));
            let mut data:HashMap<String,Value> = HashMap::new();
            $(
                data.insert($key, json!($value));
            )*
            resp.insert("data",data);
            web::Json(json!(resp))
        }
    };
    // 有$msg的情况
    ($msg:expr,  $($key:expr => $value:expr),* $(,)?) => {
       {
            let mut resp = HashMap::new();
            resp.insert("success", json!(false));
            resp.insert("msg", json!($msg));
            let mut data:HashMap<String,Value> = HashMap::new();
            $(
                data.insert($key, json!($value));
            )*
            resp.insert("data",json!(data));
            web::Json(json!(resp))
        }
    };
}

注意:过程宏需要定义在一个单独的crate中,主要是因为过程宏是一段在编译crate前,对其代码进行加工的代码,而这段是需要在编译后执行的。若是将定义过程宏和使用过程宏放到同一个crate中,就会陷入编译“死锁”:

另一个文件对其进行调用

// 注意是在crate下面的
use crate::success;
use actix_web::{
    get,web::{self, Json},
};
use serde_json::{json, Value};
use std::collections::HashMap;

#[get("/login")]
async fn login() -> Json<Value> {
    let resp = success!(
        "success",
        "key1"=> vec![1,2,3,4,5],
        "key2" =>"qwer",
        "key3"=>String::from("value")
    );
    resp
}

我理解的这个宏就是字符串替换,因为他是编译阶段处理的,所以宏所在rs文件的use是无效的,即使用了宏的文件需要对于宏使用的第三方库进行use,这个有点恶心,问题不大。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1518398.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《JAVA与模式》之抽象工厂模式

系列文章目录 文章目录 系列文章目录前言一、使用简单工厂模式的解决方案二、引进抽象工厂模式三、抽象工厂模式结构四、抽象工厂模式的优缺点前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看…

MC78L05ACDR2G线性稳压器芯片中文资料规格书PDF数据手册引脚图参数图片价格

产品概述&#xff1a; MC78L00A系列线性稳压器价格便宜&#xff0c;易于使用&#xff0c;适用于各种需要最高100mA的调节电源的应用。与大功率MC7800和MC78M00系列一样&#xff0c;这款稳压器也提供内部电流限制和高温关断&#xff0c;因此非常坚固耐用。在很多应用中&#xf…

提高工作效率,这 10 款 AI 工具不能错过

作为一个职场打工人&#xff0c;我深知时间和效率的重要性。正是因为如此&#xff0c;我开始使用各种人工智能工具来帮助我提高工作效率。在这篇文章中&#xff0c;我将会分享 10 款必备的 AI 工具&#xff0c;这些工具可以让你的工作更加高效&#xff0c;从而为你节省更多的时…

windows 11访问Debian10上的共享目录

步骤 要在Windows 11上访问Debian 10.0.0的共享目录&#xff0c;可以通过以下步骤来实现&#xff1a; 1. 设置Samba服务&#xff1a;在Debian系统上&#xff0c;需要安装并配置Samba服务&#xff0c;以便能够实现文件夹共享。Samba是一个允许Linux/Unix服务器与Windows操作系…

Windows系统搭建Cloudreve结合内网穿透打造可公网访问的私有云盘

目录 ⛳️推荐 1、前言 2、本地网站搭建 2.1 环境使用 2.2 支持组件选择 2.3 网页安装 2.4 测试和使用 2.5 问题解决 3、本地网页发布 3.1 cpolar云端设置 3.2 cpolar本地设置 4、公网访问测试 5、结语 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站&#xff…

C#,数值计算,数据测试用的对称正定矩阵(Symmetric Positive Definite Matrix)的随机生成算法与源代码

C.Hermite 1、对称矩阵 对称矩阵(Symmetric Matrices)是指以主对角线为对称轴,各元素对应相等的矩阵。在线性代数中,对称矩阵是一个方形矩阵,其转置矩阵和自身相等。1855年,埃米特(C.Hermite,1822-1901年)证明了别的数学家发现的一些矩阵类的特征根的特殊性质,如称为埃…

AI智能电话机器人的核心技术是什么?

电话机器人是近几年兴起的人工智能产品&#xff0c;它主要通过电话群呼潜在客户&#xff0c;沟通进行信息筛选&#xff0c;帮助企业选择意向客户。企业使用电话机器人可以减少人工成本&#xff0c;提高工作效率。我们一起来看看智能电话机器人的核心技术是什么&#xff1f; 电话…

Tengine编译安装

首先下载源码 可以去官网&#xff1a;The Tengine Web Server 当前最新版地址&#xff1a;https://tengine.taobao.org/download/tengine-3.1.0.tar.gz 安装编译依赖 yum -y install gcc pcre-devel zlib-devel openssl-devel libxml2-devel \libxslt-devel gd-devel GeoIP…

安装linux_centos7虚拟机_开启网络_ssh_防火墙

文章目录 安装linux_centos7虚拟机_开启网络_ssh_防火墙安装centos7虚拟机1. 进入VMware --> 点击文件 --> 新建虚拟机2. 选择典型 --> 选择下一步3. 选择--> 稍后安装操作系统4. 选择--> Linux --> CentOS 7 64位5. 在虚拟机名称输入(虚拟机名) --> 选择…

一条 SQL 更新语句如何执行的

Server 层 存储引擎层 总流程 查询语句 连接器 查询缓存 分析器 优化器 执行器 更新语句 redo log&#xff08;节省的是随机写磁盘的 IO 消耗&#xff08;转成顺序写&#x…

windows达梦安装

1.首先准备好windows安装系统&#xff0c;准备工作的做好&#xff0c;然后把素材包dm8_20230418_x86_win_64放进去&#xff0c;进行解压 解压完成之后&#xff0c;把dm8_20230418_x86_win_64再次进行解压&#xff0c;然后点击安装setup进行安装 然后点击接受进行下一步&#xf…

网络安全msf学习1

工具&#xff1a;netcat 用途 &#xff1a;端口连接、数据提交 工具nmap 用途&#xff1a;端口扫描、服务识别、操作系统指纹识别 工具 httprint 用途&#xff1a;通过远程http指纹判断http服务类型 工具&#xff1a; tamper ie 用途&#xff1a; http数据包修改、转发工…

直方图及数据95%置信区间及特征筛选

rm(list ls()) library(Rmisc) library(ggplot2) library(dplyr)data <- iris x<-iris$Sepal.Length #求置信区间方法1## confidence_interval <- t.test(x)$conf.int print(confidence_interval) #[1] 5.709732 5.976934 #attr(,"conf.level") #[1] 0.95#…

翻转时钟效果

时分秒三个部分结构功能完全一致&#xff0c;均有四块构成&#xff0c;上下各两块。 正面可见&#xff0c;背面不可见&#xff0c;同时需要调整翻转过程中的z-index。 初始状态card2为已经翻转状态。 calendar.html <!DOCTYPE html> <html lang"en">&…

Excel第26享:模糊查找之Hlookup函数与通配符的嵌套

1、需求描述 如下图所示&#xff0c;现第一行有三个参考值&#xff1a;人S、羊E、猪3&#xff0c;在第三行有5个字&#xff1a;马、牛、人、羊、猪&#xff0c;每个字如果出现在第一行的三个参考值中&#xff0c;就返回该单元格的数值。如&#xff0c;人&#xff0c;就返回“人…

unicloud update 修改

update 修改 使用腾讯云时更新方法必须搭配doc、where方法使用&#xff0c;db.collection(‘test’).update()会报如下错误&#xff1a;param should have required property ‘query’ collection.doc().update(Object data)未使用set、remove更新操作符的情况下&#xff0c…

vue:功能:table动态合并+前端导出

场景&#xff1a;第一列WM 名字相同&#xff0c;行内合并&#xff0c;后面的列合并的行数根据第一列合并的行来。第二列‘累计请假天数根据合并的几列显示数值。后续需合并的列以第一列合并行数为基准 注&#xff09;当前数据表头固定&#xff0c;行内数据不固定。以第一列WM为…

主板维修一般多少钱?电脑主板常见维修方法交换法

修主板一般要多少钱&#xff1f; 下面就让我们一起来了解一下吧。 电脑主板维修价格根据损坏程度不同而不同 1、电容器最容易损坏。 如果只是更换电容的话&#xff0c;大约需要50元左右。 2、如果主板上的电路损坏&#xff0c;面积越大&#xff0c;价格就越贵&#xff0c;可…

产品必会的6个Axure使用技巧(高阶)

1. 事件也可以复制/剪切/粘贴 只需要选中事件&#xff0c;复制/剪切&#xff0c;再选择其它事件&#xff0c;即可粘贴到这个事件上。同时支持跨页面的复制粘贴。 2. Axure支持复制粘贴Excel里的表格 具体操作 在excel里复制具体内容&#xff0c;如下图&#xff1a; 进入axur…

ConcurrentHashMap 为什么不能插入 null?

1、典型回答 简单来说&#xff0c;ConcurrentHashMap 不允许插入 null 值是JDK 源码规定的&#xff0c;如下源码所示(此源码基于JDK 1.8)&#xff1a; 从上述源码可以看出&#xff0c;在添加方法的第一句就加了判断&#xff1a;如果 key 值为 null 或者是 value 值为 null&…