I’m trying to serialize and deserialize the next JSON structure.
{
"objects": {
"type":4,
"ids":["D1","D2"]
},
"data": [
{
"stateticks":1798,
"faultstate":0,
"state":0
},
{
"stateticks":1798,
"faultstate":0,
"state":1
}
],
"ticks":1808
}
The tricky thing is that the type of the data
field is different per
objects.type
. I try to solve this by using traits.
See the playgound. All I can't use this method because
But this don't work because i don't know the type of data
on beforehand.
An enum would be a good option, but it doesn't work because
the type field is not with the data field.
Someone ideas how I can solve this?
The json structure must remain the same.
current code:
use serde::{Deserialize, Serialize};
// use serde_repr::{Deserialize_repr, Serialize_repr};
pub trait ObjectDataContent {}
pub trait ObjectType {}
// #[derive(Deserialize_repr, Serialize_repr, Debug)]
#[derive(Deserialize, Serialize, Debug)]
#[repr(u32)]
pub enum TLCObjectType {
Session = 0,
TLCFacilities = 1,
Intersection = 2,
SignalGroup = 3,
Detector = 4,
Input = 5,
Output = 6,
SpecialVehicleEventGenerator = 7,
Variable = 8,
}
impl ObjectType for TLCObjectType {}
// Somthing like this?
#[derive(Deserialize, Serialize, Debug)]
#[serde(tag = "t", content = "c")]
enum ObjectDataEnum {
Detector(Detector),
Inputs(Inputs),
}
#[derive(Deserialize, Serialize, Debug)]
struct Detector {
pub stateticks: u32,
pub state: u32,
pub faultstate: u32,
}
impl ObjectDataContent for Detector {}
#[derive(Deserialize, Serialize, Debug)]
struct Inputs {
pub state: u32,
pub faultstate: u32,
pub swico: u32,
}
impl ObjectDataContent for Inputs {}
#[derive(Deserialize, Serialize, Debug)]
pub struct ObjectReference<T: ObjectType> {
pub r#type: T,
pub ids: Vec<ObjectID>,
}
#[derive(Deserialize, Serialize, Debug)]
pub struct ObjectID(pub String);
#[derive(Deserialize, Serialize, Debug)]
pub struct ObjectData<C: ObjectDataContent, T: ObjectType> {
pub objects: ObjectReference<T>,
pub data: Vec<C>,
pub ticks: u32,
}
fn main() {
let obj: ObjectData<Detector, TLCObjectType> = ObjectData {
objects: ObjectReference {
r#type: TLCObjectType::Detector,
ids: vec![ObjectID("a".to_string()), ObjectID("b".to_string())],
},
data: vec![
Detector {
stateticks: 1,
state: 2,
faultstate: 3,
}
],
ticks: 100,
};
// Convert the Point to a JSON string.
let serialized = serde_json::to_string_pretty(&obj).unwrap();
println!("serialized = {}", serialized);
// Convert the JSON string back to a ObjectData.
// I need to remove the Detector
let deserialized: ObjectData<Detector, TLCObjectType> = serde_json::from_str(&serialized).unwrap();
println!("deserialized = {:?}", deserialized);
}