How can I (de)serialize object that has trait field to .ron format with an erased-serde crate?

huangapple go评论96阅读模式
英文:

How can I (de)serialize object that has trait field to .ron format with an erased-serde crate?

问题

以下是您要翻译的内容:

  1. [dependencies]
  2. ron = "0.8"
  3. serde = "1.0"
  4. erased-serde = "0.3"
  1. use serde::Serialize;
  2. trait Temp {
  3. fn temp(&self);
  4. }
  5. struct TempNum {
  6. num: i32,
  7. }
  8. impl Temp for TempNum {
  9. fn temp(&self) {}
  10. }
  11. #[derive(Serialize)]
  12. struct IncludeTrait {
  13. temps: Vec<Box<dyn Temp>>, // 这是问题
  14. }
  15. fn main() {
  16. let object = IncludeTrait { temps: vec![Box::new(TempNum { num: 123 })] };
  17. let str = ron::to_string(&object).unwrap();
  18. let object: IncludeTrait = ron::from_str(&str).unwrap();
  19. }

请注意,我已经将HTML实体编码(如&amp;&lt;)转换为正常的Rust代码。

英文:

the erased-serde example for json and cbor.

https://github.com/dtolnay/erased-serde

how can i change object with trait fields to ron format str?

  1. [dependencies]
  2. ron = &quot;0.8&quot;
  3. serde = &quot;1.0&quot;
  4. erased-serde = &quot;0.3&quot;
  1. use serde::Serialize;
  2. trait Temp {
  3. fn temp(&amp;self);
  4. }
  5. struct TempNum {
  6. num: i32,
  7. }
  8. impl Temp for TempNum {
  9. fn temp(&amp;self) {}
  10. }
  11. #[derive(Serialize)]
  12. struct IncludeTrait {
  13. temps: Vec&lt;Box&lt;dyn Temp&gt;&gt;, // this is problem
  14. }
  15. fn main() {
  16. let object = IncludeTrait { temps: vec![Box::new(TempNum { num: 123 })], };
  17. let str = ron::to_string(&amp;object).unwrap();
  18. let object: IncludeTrait = ron::from_str(&amp;str).unwrap();
  19. }

答案1

得分: 2

为使用 erased-serde,您需要将 erased_serde::Serialize 声明为您的特质的超特质,并通过它为 dyn Temp 实现 Serialize(您可以使用 erased_serde::serialize_trait_object!() 来实现这一点):

  1. use serde::Serialize;
  2. trait Temp: erased_serde::Serialize {
  3. fn temp(&amp;self);
  4. }
  5. erased_serde::serialize_trait_object!(Temp);
  6. #[derive(Serialize)]
  7. struct TempNum {
  8. num: i32,
  9. }
  10. impl Temp for TempNum {
  11. fn temp(&amp;self) {}
  12. }
  13. #[derive(Serialize)]
  14. struct IncludeTrait {
  15. temps: Vec&lt;Box&lt;dyn Temp&gt;&gt;
  16. }

然而,即使这样只有支持序列化,从您的代码来看,您似乎还希望支持反序列化。特质对象的反序列化是复杂的 - 我们无法知道要构建什么对象。但是我们有 typetag crate 来处理这个问题。只需在特质和实现上方添加 #[typetag::serde]

  1. use serde::{Deserialize, Serialize};
  2. #[typetag::serde]
  3. trait Temp {
  4. fn temp(&amp;self);
  5. }
  6. #[derive(Serialize, Deserialize)]
  7. struct TempNum {
  8. num: i32,
  9. }
  10. #[typetag::serde]
  11. impl Temp for TempNum {
  12. fn temp(&amp;self) {}
  13. }
  14. #[derive(Serialize, Deserialize)]
  15. struct IncludeTrait {
  16. temps: Vec&lt;Box&lt;dyn Temp&gt;&gt;
  17. }

注意:我将HTML实体(如 &amp;&lt;)保留为原样,您在代码中可能需要将它们替换为正常的符号。

英文:

To use erased-serde, you need to declare erased_serde::Serialize as a supertrait of your trait and implement Serialize for dyn Temp via that (you can do that with erased_serde::serialize_trait_object!()):

  1. use serde::Serialize;
  2. trait Temp: erased_serde::Serialize {
  3. fn temp(&amp;self);
  4. }
  5. erased_serde::serialize_trait_object!(Temp);
  6. #[derive(Serialize)]
  7. struct TempNum {
  8. num: i32,
  9. }
  10. impl Temp for TempNum {
  11. fn temp(&amp;self) {}
  12. }
  13. #[derive(Serialize)]
  14. struct IncludeTrait {
  15. temps: Vec&lt;Box&lt;dyn Temp&gt;&gt;,
  16. }

However, even that helps only with serialization, and from your code it looks like you also want to support deserialization. Deserialization of trait object is complicated - we can't know what object to construct. But we have the typetag crate for that. Just add #[typetag::serde] on top of the trait and the impls:

  1. use serde::{Deserialize, Serialize};
  2. #[typetag::serde]
  3. trait Temp {
  4. fn temp(&amp;self);
  5. }
  6. #[derive(Serialize, Deserialize)]
  7. struct TempNum {
  8. num: i32,
  9. }
  10. #[typetag::serde]
  11. impl Temp for TempNum {
  12. fn temp(&amp;self) {}
  13. }
  14. #[derive(Serialize, Deserialize)]
  15. struct IncludeTrait {
  16. temps: Vec&lt;Box&lt;dyn Temp&gt;&gt;,
  17. }

huangapple
  • 本文由 发表于 2023年2月14日 01:46:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/75439488.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定