首页 > 其他分享 >Rust解析JSON,结构体序列化和反序列化

Rust解析JSON,结构体序列化和反序列化

时间:2024-03-14 14:45:48浏览次数:27  
标签:serde pet json JSON phrase 序列化 Rust Bond

Rust

参考教程:Here

JSON一种常用的由键值对组成的数据对象;本文将通过多个例子讲解在Rust中如何解析JSON内容,以及如何将结构体转换成JSON字符串。

在Rust中解析JSON文本通常需要使用一个JSON库。Rust标准库中有一个名为serde的库,它提供了序列化和反序列化结构体和其他数据类型的功能,包括JSON。

添加依赖

要使用serde库解析JSON文本,你需要添加serdeserde_json依赖到你的项目中;

Cargo.toml文件中添加以下行:

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

解析JSON

对未类型化的JSON进行解析

任何有效的JSON数据都可以转换成serde_json::Value数据结构:

enum Value {
    Null,
    Bool(bool),
    Number(Number),
    String(String),
    Array(Vec<Value>),
    Object(Map<String, Value>),
}

以下函数可用于将JSON数据解析成serde_json::Value结构:

  • serde_json::from_str,用于解析JSON字符串;
  • serde_json::from_slice,用于对字节切片&[u8]进行解析;
  • serde_json::from_reader,从支持io::Read特性的对象中读取数据并解析,比如一个文件或TCP流;

一个使用serde_json::from_str的例子:

fn main() {

    // 一个&str类型的JSON数据
    let data = r#"
        {
            "name": "James Bond",
            "age": 33,
            "pet_phrase": [
                "Bond, James Bond.",
                "Shaken, not stirred."
            ]
        }"#;

    // 转换成serde_json::Value结构
    let v: serde_json::Value = serde_json::from_str(data).unwrap();

    // 通过方括号建立索引来访问部分数据
    println!("NAME: {}\nAGE: {}\n\t{}\n\t{}",
        v["name"],
        v["age"],
        v["pet_phrase"][0],
        v["pet_phrase"][1],
    );
}

程序运行结果

NAME: "James Bond"
AGE: 33
        "Bond, James Bond."
        "Shaken, not stirred."

将JSON解析到数据结构

serde提供了一种将JSON数据自动映射到Rust数据结构的方法;

修改前一个例子:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: u8,
    pet_phrase: Vec<String>,
}

fn main() {

    // 一个&str类型的JSON数据
    let data = r#"
        {
            "name": "James Bond",
            "age": 33,
            "pet_phrase": [
                "Bond, James Bond.",
                "Shaken, not stirred."
            ]
        }"#;

    // 转换成 Person 结构
    let p: Person = serde_json::from_str(data).unwrap();

    // 通过方括号建立索引来访问部分数据
    println!("NAME: {}\nAGE: {}\n\t{}\n\t{}",
        p.name,
        p.age,
        p.pet_phrase[0],
        p.pet_phrase[1],
    );
}

该程序运行效果与上一个例子相同,但这一次我们将serde_json::from_str函数的返回值分配给了一个自定义的类型Person

JSON数据与结构体定义不符时将产生错误;

将数据结构转换成JSON字符串

以下是一些可以将数据结构转换成JSON数据的函数:

  • serde_json::to_string,将数据结构转换成JSON字符串;
  • serde_json::to_vec,将数据结构序列化为Vec<u8>
  • serde_json::to_writer,可以序列化到任何实现了io::Write特性的对象中,例如文件或 TCP 流;

使用serde_json::to_string的一个例子:

use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
struct Person {
    name: String,
    age: u8,
    pet_phrase: Vec<String>,
}

fn main() {

    let mut pp = Vec::new();
    pp.push("hello world".to_string());
    pp.push("perfcode.com".to_string());

    let p = Person {
        name: "ho".to_string(),
        age: 18,
        pet_phrase: pp,
    };

    // 序列化为JSON字符串
    let s = serde_json::to_string(&p).unwrap();

    println!("{}",s);
    
}

程序运行效果

{"name":"ho","age":18,"pet_phrase":["hello world","perfcode.com"]}

json!宏

serde提供了一个json!宏来非常自然的构建serde_json::Value对象:

use serde_json::json;

fn main() {

    let info = json!(
        {
            "name": "James Bond",
            "age": 33,
            "pet_phrase":[
                "Bond, James Bond.",
                "Shaken, not stirred."
                ]
        }
    );

    // 通过方括号建立索引来访问部分数据
    println!("NAME: {}\nAGE: {}\n\t{}\n\t{}",
        info["name"],
        info["age"],
        info["pet_phrase"][0],
        info["pet_phrase"][1],
    );

    //序列化
    println!("{}",info.to_string());

}

程序运行效果

NAME: "James Bond"
AGE: 33
        "Bond, James Bond."
        "Shaken, not stirred."
{"age":33,"name":"James Bond","pet_phrase":["Bond, James Bond.","Shaken, not stirred."]}

Value::to_string方法可以将serde_json::Value对象转换成 JSON 字符串;

标签:serde,pet,json,JSON,phrase,序列化,Rust,Bond
From: https://www.cnblogs.com/RioTian/p/18072802

相关文章

  • fastjson改造
    背景fastjson太过于侧重性能,对于部分高级特性支持不够,而且部分自定义特性完全偏离了json和js规范导致和其他框架不兼容;fastjson文档缺失较多,部分Feature甚至没有文档,而且代码缺少注释较为晦涩;fastjson的CVEbug监测较弱,很多CVE数据库网站上有关fastjson的CVE寥寥无几,例如近......
  • Rust 标准库 Trait 指南
    部分内容来自Rust2021年期刊内容目录引言Trait基础自动Trait泛型Trait格式化Trait操作符Trait转换Trait错误处理迭代器TraitI/OTrait总结引言你是否曾想过下面这些trait有什么不同?Deref<Traget=T>,AsRef<T>,以及Borrow<T>?Clone,Copy,和ToOwned?From......
  • Serializer 序列化 -----视图层传入一个变量到序列化器的方法
    fromrest_frameworkimportserializersclassMyModelSerializer(serializers.ModelSerializer):classMeta:model=MyModelfields=['field1','field2']defto_representation(self,instance):......
  • 2024HVV行动-进军蓝中研判(log4j2、fastjson、Struts2、Shiro)
    1、log4j2特征:恶意请求中包含JNDI协议地址,如"ldap://"、"rmi://"等,被log4j2解析为JNDI查找。原理:在日志输出中,未对字符进行严格的过滤,执行了JNDI协议加载的远程恶意脚本,从而造成远程代码执行。影响:严重的RCE,2.0≤ApacheLog4j2<2.15.0-rc2攻击字段:${jndi......
  • Flutter中JSON、List和Map之间的相互转换
    JSON转换为Map要将JSON字符串转换为Dart的Map对象,您可以使用Flutter的内置json库。这个库提供了jsonDecode()函数,可以将JSON字符串解析为Dart的Map对象import'dart:convert';StringjsonString='{"name":"John","age":30}';Map<String,dynamic>us......
  • Rust的Cell、RefCell和OnceCell:灵活且安全的内部可变性
    这一系列文章的创作目的主要是帮助我自己深入学习Rust,同时也为已经具备一定Rust编程经验,但还没有深入研究过语言和标准库的朋友提供参考。对于正在入门Rust的同学,我更建议你们看《Rust圣经》或者《TheBook》,而不是这种晦涩难懂的文章。终于拿到了某量化公司的offer,继续系列文......
  • 【Web】浅聊XStream反序列化本源之恶意动态代理注入
    目录简介原理复现具体分析之前我们反序列化了个什么?XStream反序列化的朴素通识具体分析第一步:unmarshal解组第二步:readClassType获取动态代理类的Class对象第三步:调用convertAnother对动态代理类进行实例化第四步:调用动态代理类方法触发invoke前文:【Java】萌新的......
  • Java 简单 bean 与 json 互相转换
    场景说明最近在写一个服务,经常用到调别人接口得到json,然后需要转换为指定bean,记录一下常用工具类引入依赖<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId></dependency><dependency>......
  • 复现反序列化
    1、复现shiro的反序列化漏洞,实现反弹shell2、演示渗透测试和打点的手段,说明二者的区别一个指定了资产范围,一个从公司名开始收集3、描述hw蓝方有哪些组,工作内容有什么监测组:看态势感知,waf,写日报判断告警是否为真实告警研判组:处置组:根据真实告警,防火墙封禁攻击IP溯源组:尝试......
  • Java 数组转 JSON数组
    场景说明最近在开发一个推送数据到MQ的服务,下游要求将数组转换为JSON形式后进行推送引入依赖<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.5</version&......