Can't Deserialize JSON

Hi, I've been struggling for a few hours trying to parse a simple JSON string to a struct. WHY is this so hard??? :cry:

I have a websocket connection handler here handling an incoming message:

async fn client_msg(client_id: &str, msg: Message, clients: &Clients) {
    println!("received message from {}: {:?}", client_id, msg);

    let message = match msg.to_str() {
        Ok(v) => v,
        Err(_) => return,
    };

    let locked = clients.lock().await;
    match locked.get(client_id) {
        Some(v) => {
            if let Some(sender) = &v.sender {
                println!("Got message from a sender!");
                
                #[derive(Debug, Deserialize)]
                struct L0 {
                    action_type: String,
                }   

                let json_result: Result<L0, _> = serde_json::from_str(message);

                match json_result {
                    Ok(v) => {
                        println!("Unpacked msg json! {:?}", v);
                      
                        sender.send(Ok(Message::text("yeahh"))).unwrap();
                    }
                    Err(err) => {
                        println!("{:?}", err);
                        sender.send(Ok(Message::text("invalid JSON 😢"))).unwrap();
                        return;
                    }
                };

            }
        }
        None => return,
    }

}

I used a string to json converting site to generate this text: "{\n "action_type": “bar”\n}\n"

When I send this text as the post body it results in error every time that serde can't parse the json...

Here is my server console output:

received message from e303c8003c4a491caa7f322b479c5e78: Text(""{\n \"action_type\": “bar”\n}\n"")
Got message from a sender! ""{\n \"action_type\": “bar”\n}\n""
Error("invalid type: string "{\n \"action_type\": “bar”\n}\n", expected struct L0", line: 1, column: 40)

Can anyone help me understand the problem here? I AM sending JSON in the correct form for my struct L0 so I don't understand why the parsing fails here...

When I hardcode this var message like this:

let message = "{\n    \"action_type\": \"bar\"\n}\n";

the serde parsing finishes successfully!!

But how can I get it to send like this over the network? :thinking:

I am trying to send different forms of this JSON from my websocket client but nothing works...

{action_type: “bar”} -> Error("key must be a string", line: 1, column: 2)

{“action_type": “bar”} -> Error("key must be a string", line: 1, column: 2)

“{action_type: “bar”}” -> Error("expected value", line: 1, column: 1)

"{\n "action_type": "bar"\n}\n" -> Error("invalid type: string "{\n \"action_type\": \"bar\"\n}\n", expected struct L0", line: 1, column: 38)

What is tarnation does it want me to send???? :face_with_symbols_over_mouth: :tired_face:

Out of the four variants you have listed here, only {“action_type": “bar”} is close to being JSON. It uses the wrong quotes. You want to use the ASCII quotes " in all cases. The typographic quotes do cause the "key must be a string" error you see here.

The working text you posted first

let message = "{\n    \"action_type\": \"bar\"\n}\n";

is the JSON

{
    "action_type": "bar"
}

It does use the ASCII " characters.

The messages from you original post show two quote characters after Text(.

    received message from e303c8003c4a491caa7f322b479c5e78: Text(""{\n \"action_type\": “bar”\n}\n"")

This looks like you are transmitting this JSON. It is valid, but it is a single string and cannot be parsed as the struct L0.

"{\n \"action_type\": “bar”\n}\n"
4 Likes

This seems the closest. Are you representing the message accurately? Because it contains fancy unicode quotation marks and , not the plain ASCII " – so if you copy-pasted that faithfully, is that simply the issue you’re having?

2 Likes

The double quotes in that string around bar are not ascii quotes (notice they look a little different), so when you escape them with backslash you get an invalid escape sequence.

1 Like

Thanks everybody! Very annoying that my keyboard makes the quotes that aren't recognized, but I got it working my sending this from my ws client:

{"action_type": "bar"}

Thanks!

That's usually an option that you can turn off (often called “smart quotes” because it guesses whether to write a or a character based on the text), and text editors meant for programming will not do it by default. What operating system and text editor are you using? We might be able to help.

1 Like