我有一个数据结构 Listener listener = new Listener(
onPointerUp: (PointerUpEvent event) {
print('${event.position}');
final RenderBox box = context.findRenderObject();
final Offset localOffset = box.globalToLocal(event.position);
print(box);
var res = BoxHitTestResult();
box.hitTest(res, position: localOffset);
for (var r in res.path) {
if (r.target is RenderMetaData) {
var target = r.target as RenderMetaData;
print(target.metaData);
}
}
});
,我想将该序列化为其他Rust结构。它基本上是内部字段的Document
,但是它与数据库API交互,因此,我肯定会希望将其他类型转换为这些HashMap
。
例如这个结构
Document
我已经使用struct Entry {
id: String,
user: String,
duration: u32,
location: (f64, f64),
}
特性转换为Document
类型,但是当From
结构更改时,这是我必须修改的额外地方。该实现使用Entry
,如下所示:
DocumentBuilder
impl From<Entry> for Document {
fn from(entry: Entry) -> Self {
Document::builder()
.name(&entry.id) // set the name of the document
.field("user", entry.user) // add fields ...
.field("duration", entry.duration)
.field("location", entry.location)
.build() // build a Document
}
}
方法可以将可以转换为field
的任何值分配给键。因此FieldValue
的签名是:
field
我想使用serde及其派生功能将结构及其字段自动序列化为impl DocumentBuilder {
// ...
pub fn field<T: Into<FieldValue>>(mut self, key: &str, value: T) -> Self { ... }
// ...
}
。我将如何去做呢?我查看了Implementing a Serializer的Wiki,但显示的示例写入了一个字符串,我想知道如何使用构建器模式将其序列化为数据结构。
答案 0 :(得分:1)
最简单的方法是使用serde_json::from_value
(即使您不使用JSON也适用,但要求所有字段均为有效JSON [例如,哈希图中没有非字符串键]):< / p>
let entry = Entry {
a: 24,
b: 42,
c: "nice".to_string()
};
let v = serde_json::to_value(&entry).unwrap();
let document: Document = serde_json::from_value(v).unwrap();
注意:Document
的值类型必须实现Deserialize
,并且必须以某种方式将任何值反序列化为正确的参数。可以使用#[serde(untagged)]
完成此操作,但是可能会导致某些类型错误,例如将u8
转换为u64
。
一种不涉及任何不必要的副本的更复杂的方法将要求您编写一个自定义(De)序列化器,而一个很好看的方法是serde_transcode::transcode
,它与您所做的事情相反想要-它在两种数据格式之间转换。