Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get json value from byte using rust

Tags:

json

byte

rust

I need to get the name from a base64 value, I tried like following but I didn't able to parse it and get the name property, any idea how can I do it ?

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

}

The value represnt json like

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

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

At the end I need to print "name": "John Doe"

this is the decoded value

enter image description here

like image 972
Jenney Avatar asked Sep 04 '26 19:09

Jenney


2 Answers

Masklinn explains why you have an error, and you should read his answer.

But IMO the simplest and safest solution is to use serde's derive to decode into the desired structure:

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);
}
like image 66
Denys Séguret Avatar answered Sep 06 '26 09:09

Denys Séguret


Denys has provided for the usual way to use serde, and you should definitely apply their solution if that's an option (if the document is not dynamic).

However:

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

Have you considered at least following the indications of the compiler? The Rust compiler is both pretty expressive and very strict, if you give up at every compilation error without even trying to understand what's happening, you'll have a very hard time.

If you try to compile your snippet, the first thing it tells you is

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

and while it doesn't always work out perfectly, the compiler's suggestion is spot-on: base64 has to allocate space for the return value so it yields a Vec, but serde_json doesn't really care where the data comes from so it takes a slice. Just referencing (applying the & operator) the vec allows rustc to coerce it to a slice.

The second suggestion is:

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

which doesn't provide a solution but a simple unwrap would do for testing. However you really want to read up on Rust error handling as Result is very much the normal way to signal fallibility / errors, and thus like compiler errors you will also encounter it a lot.

Anyway that yields a proper serde_json::value::Value, which you can manipulate the normal way e.g.

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

will return an Option<&str> of value None if the key is missing or not mapping to a string, and Some(s) if the key is present and mapping to a string: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5025d399644694b4b651c4ff1b9125a1

like image 33
Masklinn Avatar answered Sep 06 '26 08:09

Masklinn



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!