Bria
February 20, 2023, 5:44am
1
I have the following trait and type:
trait Previous {}
trait ToSerde {}
#[derive(Clone, Serialize, Deserialize)]
struct MyStruct<T>(T);
impl<T: Previous + Serialize> ToSerde for MyStruct<T> {}
impl Previous for i32 {}
And If I need to serialize the following my_struct_box
: Box<dyn ToSerde>
:
let my_struct = MyStruct(1i32);
let my_struct_box: Box<dyn ToSerde> = my_struct_box(my_struct);
I can use the package typetag like this:
trait Previous {}
#[typetag::serialize(tag = "to_serde")]
trait ToSerde {}
#[derive(Clone, Serialize, Deserialize)]
struct MyStruct<T>(T);
#[typetag::serialize]
impl<T: Previous + Serialize> ToSerde for MyStruct<T> {}
impl Previous for i32 {}
But the package can not Deserialize
my_struct_box
.
So, put others like safety, performace aside, is there any way to deserialize the object serialized from my_struct_box
?
Replace typetag::serialize
with typetag::serde
so you get the deserialize impls
1 Like
Bria
February 20, 2023, 6:16am
3
I tried this:
trait Previous {}
#[typetag::serde(tag = "to_serde")]
trait ToSerde {}
#[derive(Clone, Serialize, Deserialize)]
struct MyStruct<T>(T);
#[typetag::serde]
impl<T: Previous + Serialize> ToSerde for MyStruct<T> {}
impl Previous for i32 {}
But it has compile error:
error: deserialization of generic impls is not supported yet; use #[typetag::serialize] to generate serialization only
--> src\ofac.rs:560:5
|
560 | impl<T: Previous + Serialize> ToSerde for MyStruct<T> {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^
Bria
February 20, 2023, 6:36am
4
The following is the broader context I am facing:
trait Previous {
fn get_i32(&self) -> i32;
}
#[typetag::serialize(tag = "to_serde")]
trait ToSerde {
fn calc(&self) -> i32;
}
#[derive(Clone, Serialize, Deserialize)]
struct MyStruct<T>(T);
#[typetag::serialize]
impl<T: Previous + Serialize> ToSerde for MyStruct<T> {
fn calc(&self) -> i32 {
self.0.get_i32() + 1
}
}
#[derive(Clone, Serialize, Deserialize)]
struct MyType1;
#[derive(Clone, Serialize, Deserialize)]
struct MyType2;
#[derive(Clone, Serialize, Deserialize)]
struct MyType3;
impl Previous for MyType1 {
fn get_i32(&self) -> i32 { 1 }
}
impl Previous for MyType2 {
fn get_i32(&self) -> i32 { 2 }
}
impl Previous for MyType3 {
fn get_i32(&self) -> i32 { 3 }
}
struct SaveAsFile {
box_vec: Vec<Box<dyn ToSerde>>
}
impl SaveAsFile {
fn final_calc(&self) -> Vec<i32> {
self.box_vec.iter()
.map(|x| x.calc())
.collect()
}
}
It takes long time to get a instance of SaveAsFile
, which I need to save it on a local file. There is many MyType
to be a field of MyStruct
, so I seems that generic implementing like impl<T: Previous + Serialize> ToSerde for MyStruct<T>
is unavoidable.
Oh my bad, I hadn't run into that restriction before.
I'm not sure there's a great way to make that work. There's an open issue in the repo but it doesn't look like there's consensus on how it should be implemented.
I think it should be possible to create a second layer of typetag traits for the inner type and then implement ToSerde
for a boxed trait object of that inner trait.
use serde::{Deserialize, Serialize};
use std::fmt::Debug;
#[typetag::serde(tag = "previous")]
trait Previous {
fn as_debug(&self) -> &dyn Debug;
}
#[typetag::serde(tag = "to_serde")]
trait ToSerde {
fn previous(&self) -> &dyn Previous;
}
#[derive(Clone, Serialize, Deserialize)]
struct MyStruct<T>(T);
impl<'a, T: Previous + 'a> MyStruct<T> {
fn box_inner(self) -> MyStruct<Box<dyn Previous + 'a>> {
MyStruct(Box::new(self.0))
}
}
#[typetag::serde]
impl ToSerde for MyStruct<Box<dyn Previous>> {
fn previous(&self) -> &dyn Previous {
&*self.0
}
}
#[typetag::serde]
impl Previous for i32 {
fn as_debug(&self) -> &dyn Debug {
self
}
}
fn main() {
let my_struct = MyStruct(1i32);
let my_struct_box: Box<dyn ToSerde> = Box::new(my_struct.box_inner());
let string = serde_json::to_string_pretty(&my_struct_box).unwrap();
println!("{string}");
let de: Box<dyn ToSerde> = serde_json::from_str(&string).unwrap();
println!("Deserialized value: {:?}", de.previous().as_debug());
}
Output:
{
"to_serde": "MyStruct",
"previous": "i32",
"value": 1
}
Deserialized value: 1
Kind of awkward but it does work
2 Likes
system
Closed
May 21, 2023, 6:45am
6
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.