如何解决使用into_serde反序列化字符串会使应用程序惊慌失措
与我的一个朋友一起,我们试图使用RUST中的serde_json
板条箱反序列化WebSocket发送的某些消息。
我们遇到一个特定的错误,我们设法通过以下代码片段重新创建了它:
use serde::{Deserialize,Serialize};
#[derive(Deserialize,Debug)]
struct EffetSer {
test: String
}
fn main() {
let test_value = JsValue::from_str("{\"test\": \"value\"}");
let test_value: EffetSer = test_value.into_serde().unwrap();
log::error!("WOW : {:?}",test_value);
}
我们的TOML具有以下依赖性:
wasm-bindgen = { version = '0.2.63',features = ['serde-serialize'] }
serde = { version = '1.0',features = ["derive"] }
serde_json = '1.0.55'
js-sys = '0.3.40'
错误如下:
app.js:310 panicked at 'called `Result::unwrap()` on an `Err` value: Error("invalid type: string \"{\\\"test\\\": \\\"value\\\"}\",expected struct EffetSer",line: 1,column: 23)'
任何帮助将不胜感激,因为我们仍在努力了解我们在做什么错以及为什么我们不能对字符串反序列化。
解决方法
问题可能是对into_serde
语义的误解。
根据documentation,它的工作方式如下:
对此值调用JSON.stringify,然后将生成的JSON解析为任意Rust值。
换句话说,其语义如下:
- 将
JsValue
的每个组成部分转换为相应的serde
内部元素; - 从给定的组件树中反序列化所需的类型。
现在,在我们的案例中这意味着什么?好吧,您使用JsValue::from_str
创建了JsValue
,再次根据文档,
创建一个新的JS值,它是一个字符串。
因此,JsValue
并不是一个对象,就像您可能会假设的那样;它是一个原语-一个字符串,它恰好具有对象的JSON表示形式。然后,当您调用from_serde
时,Serde看到的字符串-不是作为输入,而是作为内部表示,不能转换为对象。
现在,该怎么办?有几种方法可以修复此代码:
- 首先也是最明显的一点:根本不使用
JsValue
,直接与&str
从serde_json::from_str
反序列化。 - 使用js_sys::JSON::parse从字符串中获取类似对象的
JsValue
,然后使用EffetSer
将其转换为into_serde
。这可能效率不高,因为它需要往返JSON::parse
和JSON::serialize
才能将字符串转换为对象,然后再转换回字符串。 - 编写您自己的方法,将
JsValue
直接转换为EffetSer
。但是我不确定是否可行,因为我无法找到一种从JS对象提取单个字段的方法。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。