Issue: JSON error in match from_slice(..)


#1

Hi, this might be specific to serde_json but maybe somebody here can help as well.
Thanks,


Has anyone been bitten by type inference in Rust?
#2

It works in a standalone example: play

I’d suggest printing out the body and making sure it’s what you expect.


#3

Hi vitayd,
yeah it works in your standalone example, however it’s an actual post body that I am parsing. Your standalone code proves my json is valid though.
Thanks,


#4

Yeah, but what I’m suggesting is you dump out (e.g. println!()) the data in your post to make sure it’s expected (and valid) json.


#5

If I can dump out that means I can parse it, otherwise I can only dump the bytes. I hope my question should be answered in my current code context.

The dump of the body will look like this.


#6

You should convert the raw bytes to &str and dump that - it’ll be easier to look at :slight_smile:.


#7

Already did that and that works, I’d like to solve it in the current context using serde_json. I posted an issue to serde_json github. Other way may work, but I like to solve first in this way. In my github post, I posted an example I followed.


#8

Can you post what that is in ASCII (I’m assuming that’s the encoding)? i.e. dump the string repr of the payload (body) and show it here. From some bits of it, it doesn’t appear to match the json you posted in the github issue.


#9

Ok. here’s the result if I include your code. I have two sample post, a longer one and this short. Though same error I got.

The current code is:

            let response = request.body().concat2().and_then(move |body: Chunk| {
                let v: Result<serde_json::Value, _> = serde_json::from_slice(&body);
                println!("{:?}", v);
                match from_slice(&body) {
                    Ok(payload) => {
                        println!("{:?}", payload);
                        make_response(payload)
                    }
                    Err(error) => {
                        println!(
                            "Error occured on saving transaction, error: {}",
                            error.description()
                        );
                        make_error_response(error.description())
                    }
                }
            Box::new(response)

I could not get in Ok(payload).


#10

Is there a different from_slice() in scope? i.e. why aren’t you matching on v in here:

let v: Result<serde_json::Value, _> = serde_json::from_slice(&body);
println!("{:?}", v);
match from_slice(&body) {

What is that second from_slice there?


#11

@marvsperez it is going to be pretty difficult to figure this out unless you can come up with a minimal, complete, verifiable example that fails the same way in the playground.


#12

This is a little bit better. I can achieve what I’d like to happen here. Then deserialize that to my struct. How can I do that?


#13

The second from_slice match to Err. I think without explicit annotation to Result<serde_json::Value, _> it look for struct type? :thinking:
Also the secon match from_slice is my original code I wanted to use for matching.


#14

You need to define a struct and derive Deserialize for it (unless you want/need to impl Deserialize by hand, which is very doubtful). For example:

#[macro_use]
extern crate serde;
extern crate serde_json;

#[derive(Deserialize, Debug)]
struct MyStruct {
    id: i32,
    transaction_lines: Vec<TransactionLine>,
}

#[derive(Deserialize, Debug)]
struct TransactionLine {
    amount: i32,
}

fn main() {
    let s = br#"{
    "id": 1,
    "transaction_lines": [
        {
            "amount": 100
        },
        {
            "amount": 200
        }  
    ]
}
"#;

    let s = serde_json::from_slice::<MyStruct>(s);
    println!("{:#?}", s);
}

play

P.S. Try to avoid posting screenshots - copy the code here and enclose it with triple backticks to get syntax highlighting.


#16

Sorry for the screenshot. I know I can copy code, but I just added screenshot of the result.

I think I should give up on using “match from_slice”. I like it but it doesn’t work on me. Your sample code above works for me now and I’ll use it. But will still try to make this “matching” works. Need to understand more. two weeks in rust is fun but really challenging.


#17

match serde_json::from_slice should work just fine, but you need to make sure it’s trying to deserialize into the right type. I guess it’s possible that type inference selected the target type to deserialize into, and that target type must be Deserialize as well or else the compiler would’ve complained. I’m guessing it’s whatever type is response but would need to see the rest of the code.


#18

True. I can’t find though how and where the type interference is. Once I figure it out, I’ll post an update here. For now, I’m happy what I got and can continue from here. Thank you so much for the help. I guess I will have more questions in the future. Will try it minimal code and reproducible.
Thanks again @vitalyd :raised_hands::ok_hand: