使用 Rust 从字节获取 json 值

Alb*_*rto 5 byte json rust

我需要从值中获取名称base64,我尝试了以下操作,但无法解析它并获取名称属性,知道我该怎么做吗?

extern crate base64;
use serde_json::Value;
fn main() {


    let v = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ";

    let bytes = base64::decode(v).unwrap();
    println!("{:?}", bytes);
   
   
    let v: Value = serde_json::from_slice(bytes);
    

}
Run Code Online (Sandbox Code Playgroud)

该值代表 json,例如

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}
Run Code Online (Sandbox Code Playgroud)

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1df0f644a139f8d526a44af8abf78e8e

最后我需要打印"name": "John Doe"

这是解码后的值

在此输入图像描述

Den*_*ret 6

Masklinn 解释了为什么你会出错,你应该阅读他的答案。

但在我看来,最简单、最安全的解决方案是使用serde 的导出来解码为所需的结构:

use serde::Deserialize;

/// a struct into which to decode the thing
#[derive(Deserialize)]
struct Thing {
    name: String,
    // add the other fields if you need them
}

fn main() {
    let v = "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ";
    let bytes = base64::decode(v).unwrap(); // you should handle errors
    let thing: Thing = serde_json::from_slice(&bytes).unwrap();
    let name = thing.name;
    dbg!(name);
}
Run Code Online (Sandbox Code Playgroud)


Mas*_*inn 5

Denys 提供了使用 serde 的常用方法,如果可以选择(如果文档不是动态的),您绝对应该应用他们的解决方案。

然而:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=1df0f644a139f8d526a44af8abf78e8e

您是否考虑过至少遵循编译器的指示?Rust 编译器既非常具有表现力,又非常严格,如果你在每次编译错误时都放弃,甚至没有尝试理解发生了什么,那么你会遇到非常困难的事情。

如果您尝试编译代码片段,它告诉您的第一件事是

error[E0308]: mismatched types
  --> src/main.rs:12:43
   |
12 |     let v: Value = serde_json::from_slice(bytes);
   |                                           ^^^^^
   |                                           |
   |                                           expected `&[u8]`, found struct `Vec`
   |                                           help: consider borrowing here: `&bytes`
   |
   = note: expected reference `&[u8]`
                 found struct `Vec<u8>`
Run Code Online (Sandbox Code Playgroud)

虽然它并不总是完美地工作,但编译器的建议是准确的:base64必须为返回值分配空间,以便它产生 a Vec,但serde_json并不真正关心数据来自哪里,因此它需要一个切片。只需引用(应用&运算符)vec 就可以让 rustc 将其强制转换为切片。

第二个建议是:

error[E0308]: mismatched types
  --> src/main.rs:12:20
   |
12 |     let v: Value = serde_json::from_slice(bytes);
   |            -----   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `Value`, found enum `Result`
   |            |
   |            expected due to this
   |
   = note: expected enum `Value`
              found enum `Result<_, serde_json::Error>`
Run Code Online (Sandbox Code Playgroud)

它不提供解决方案,但unwrap可以进行简单的测试。然而,你确实想阅读Rust 错误处理,因为Result这是发出错误/错误信号的正常方式,因此就像编译器错误一样,你也会经常遇到它。

无论如何,这会产生一个正确的serde_json::value::Value,你可以用正常的方式操纵它,例如

error[E0308]: mismatched types
  --> src/main.rs:12:43
   |
12 |     let v: Value = serde_json::from_slice(bytes);
   |                                           ^^^^^
   |                                           |
   |                                           expected `&[u8]`, found struct `Vec`
   |                                           help: consider borrowing here: `&bytes`
   |
   = note: expected reference `&[u8]`
                 found struct `Vec<u8>`
Run Code Online (Sandbox Code Playgroud)

如果键丢失或未映射到字符串,并且键存在并映射到字符串,则将返回Option<&str>of 值: https://play.rust-lang.org/ ?version=stable&mode=debug&edition=2018&gist= 5025d399644694b4b651c4ff1b9125a1NoneSome(s)