To parse that line I have to make two calls to serde_json::from_str now, first to get unescaped String and then to deserialize that String to struct. Using serde to avoid extra escaping looks not natural from my point of view, is there any other (faster or better) way to avoid extra escape symbols from input?
What you're seeing here is just your input string, printed as you would enter it as a Rust string literal. It still contains just what you wrote in your first code block, i.e., a JSON object within a (probably also JSON) string. Since the input is in that format (looks like someone messed up producing that file), you can't deserialize it in one step.
This to me seems perfectly reasonable, assuming that the string itself actually is encoded as a JSON string (i.e. that the escape syntax used precisely matches the escape codes available in JSON).
To my understanding, serde_json is highly optimized, and deserializing a String does extremely little work beyond validating the outer " and unescaping the contents. (it might parse an integer or a bool if you give it one, just for better diagnostics, but that's about it)
Your data simply is double-serialized, so you need two deserialize passes. Serde doesn't support this out of the box. One could probably hack up something, but it sure won't be any simpler than a call to from_str.