使用 Rust 从字节中获取 json 值

Get json value from byte using 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);
    

}

值代表json喜欢

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

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

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

这是解码后的值

Masklinn 解释了您出错的原因,您应该阅读他的回答。

但 IMO 最简单和最安全的解决方案是使用 serde's derive 解码成所需的结构:

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);
}

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>`

虽然它并不总是完美运行,但编译器的建议是正确的:base64 必须为 return 值分配 space,因此它会产生 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>`

它没有提供解决方案,但一个简单的 unwrap 可以用于测试。

这会产生一个正确的 serde_json::value::Value,您可以按正常方式对其进行操作,例如

v.get("name").and_then(Value::as_str));

将 return 一个 Option<&str>None 如果键丢失或未映射到字符串,并且 Some(s) 如果键存在并映射到字符串:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5025d399644694b4b651c4ff1b9125a1