Hi, I've been struggling for a few hours trying to parse a simple JSON string to a struct. WHY is this so hard???
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...
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.
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?
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.
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.