一种基于宏和serde_json实现的rust web中统一返回类
本人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_json的json!进行进一步封装
这里一个宏里面写两个形式,因为要匹配传入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,这个有点恶心,问题不大。
相关文章:
一种基于宏和serde_json实现的rust web中统一返回类
本人rust萌新,写web碰到了这个,基于ChatGPT和文心一言学了宏,强行把这玩意实现出来了,做个学习记录,如果有更好的方法,勿喷。 先看效果,注意不支持嵌套,且kv映射要用>(因为它这个…...
每周一算法:A*(A Star)算法
八数码难题 题目描述 在 3 3 3\times 3 33 的棋盘上,摆有八个棋子,每个棋子上标有 1 1 1 至 8 8 8 的某一数字。棋盘中留有一个空格,空格用 0 0 0 来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局…...
爬虫练习:获取某网站的房价信息
一、相关网站 二、相关代码 import requests from lxml import etree import csv with open(房天下数据.csv, w, newline, encodingutf-8) as csvfile:fieldnames [名称, 地点,价格,总价,联系电话]writer csv.DictWriter(csvfile, fieldnamesfieldnames)writer.writeheader…...
第一个C语言hello world
#include <stdio.h> int main() {printf("hello world ! \n");//打印函数return 0; } "#" : 预处理标志 include <> : 表示预处理的文件在<>内 stdio.h : 标准的io头文件 // io : 输入输出 // printf()…...
【Python】新手入门学习:详细介绍依赖倒置原则(DIP)及其作用、代码示例
【Python】新手入门学习:详细介绍依赖倒置原则(DIP)及其作用、代码示例 🌈 个人主页:高斯小哥 🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、Py…...
嵌入式驱动学习目录索引(更新中)
前言 这是一篇索引博客,用来作为索引记录学习嵌入式Linux的过程,可以用来给自己以及需要的读者作为一个目录索引,每次更新完博客都会添加进该目录中。 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程,未来预计四个月将高强度…...
ruoyi-vue插件集成websocket
链接:插件集成 | RuoYi WebSocketServer.java:补充代码 /*** 此为广播消息* param message 消息内容*/public void sendAllMessage(String message) {LOGGER.info("【websocket.sendAllMessage】广播消息:"message);try {for(String sessionI…...
华为ce12800交换机m-lag(V-STP模式)配置举例
配置## 标题思路 采用如下的思路配置M-LAG双归接入IP网络: 1.在Switch上配置上行接口绑定在一个Eth-Trunk中。 2.分别在SwitchA和SwitchB上配置V-STP、DFS Group、peer-link和M-LAG接口。 3.分别在SwitchA和SwitchB上配置LACP M-LAG的系统优先级、系统ID。 4.分别在…...
STM32第九节(中级篇):RCC——时钟树讲解(第一节)
目录 前言 STM32第九节(中级篇):RCC——时钟树讲解 时钟树主系统时钟讲解 HSE时钟 HSI时钟 锁相环时钟 系统时钟 SW位控制 HCLK时钟 PCLKI时钟 PCLK2时钟 RTC时钟 MCO时钟输出 6.2.7时钟安全系统(CSS) 小结 前言 从…...
c/c++字符串处理标准库 string 介绍
c语言中string.h介绍 C语言的标准库中包含了一个头文件 <string.h>,该头文件提供了一系列字符串处理函数的声明和定义。以下是一些常用的函数: 字符串复制:strcpy(dest, src)。将源字符串 src 复制到目标字符串 dest,包括…...
HarmonyOS NEXT应用开发之深色模式适配
介绍 本示例介绍在开发应用以适应深色模式时,对于深色和浅色模式的适配方案,采取了多种策略如下: 固定属性适配:对于部分组件的颜色属性,如背景色或字体颜色,若保持不变,可直接设定固定色值或…...
Go微服务: 基于Go Micro框架实现微服务调用
Go Micro 1 )概述 在具体的项目开发过程中,开发者聚焦的是业务逻辑的开发和功能的实现大量的环境配置,调试搭建等基础性工作会耗费相当一部分的精力因此有必要将微服务架构中所涉及到的,相关的解决方案做集中管理和维护Go Micro …...
大模型prompt提示词如何调优?
当使用大型模型(如GPT-3.5)时,可以通过优化提示(prompt)来引导模型生成更加符合预期的内容。以下是一些调优提示词的建议: 1、清晰的问题陈述:确保你的问题或提示清晰、简明,能够准…...
【Python/crawl】如何使用Python爬虫将一系列网页上的同类图片下载到本地
【需求】 从网页https://www.zhainq.com/%e7%be%8e%e5%a5%b3%e5%86%99%e7%9c%9f%e6%9c%ba%e6%9e%84/%e6%97%a5%e6%9c%ac%e7%be%8e%e5%a5%b3%e5%86%99%e7%9c%9f/109012.html 开始,有十七页,每页都有大漂亮“小濑田麻由”的若干图片,想要将其…...
Postgresql 连接数查看,死锁问题解决
-- 查看所有连接 select * -- datname,pid,application_name,state from pg_stat_activity; -- 查询最大连接数 select max_conn-now_conn as resi_conn from (select setting::int8 as max_conn,(select count(*) from pg_stat_activity) as now_conn from pg_settings where…...
ssm蛋糕甜品商城系统(程序+文档+数据库)
** 🍅点赞收藏关注 → 私信领取本源代码、数据库🍅 本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目,希望你能有所收获,少走一些弯路。🍅关注我不迷路🍅** 一、研究背景…...
算法空间复杂度计算
目录 空间复杂度定义 影响空间复杂度的因素 算法在运行过程中临时占用的存储空间讲解 例子 斐波那契数列递归算法的性能分析 二分法(递归实现)的性能分析 空间复杂度定义 空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大…...
C++ lambda函数个人理解
及方便自己在函数内部定义函数 int main() {int i 1;auto c [](int a, int c) {return ab;};int d a(2, i);cout<<c;return 0; }格式: auto functionname [capture](parameters) -> return_type { /* … */ }; (1)[capture] &a…...
SwiftUI的context Menu
SwiftUI的 context Menu 现在来演示一下如何使用 SwiftUI 的 Context Menu 。 代码: import SwiftUIstruct ContextMenuBootCamp: View {State var bgColor: Color .purplevar body: some View {VStack(alignment: .leading, spacing: 10.0) {Image(systemName: …...
【数据结构】树与堆 (向上/下调整算法和复杂度的分析、堆排序以及topk问题)
文章目录 1.树的概念1.1树的相关概念1.2树的表示 2.二叉树2.1概念2.2特殊二叉树2.3二叉树的存储 3.堆3.1堆的插入(向上调整)3.2堆的删除(向下调整)3.3堆的创建3.3.1使用向上调整3.3.2使用向下调整3.3.3两种建堆方式的比较 3.4堆排…...
wordpress后台更新后 前端没变化的解决方法
使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
