Hi Community!
I'm trying to get my head around serde
better, and I would like to understand if it covers cases like this.
- Transform e.g. such structure of rust object
[ ... {"name": "field_name", "value": 1} ... ]
to JSON string like{ ... "field_name": 1 ... }
of arbitrary message - Use some descriptor object (unknown at compile) that contains custom rules on how to handle the specified field values, etc.
Note: I got help how to solve when we Deserialize the JSON - string. And now I am wondering how to solve this for the Serialize action
There is some code snippet with examples is in the attachment.
Thank you in advance!
use serde; // 1.0.130
use serde::{Serialize, Deserialize};
use serde_json; // 1.0.69
use std::collections::HashMap;
// The following structs define the structure of the message
#[derive(Debug, Serialize, Deserialize)]
#[serde(transparent)]
struct MessageValue {
fields: Vec<FieldValue>
}
#[derive(Debug, Serialize, Deserialize)]
struct FieldValue {
name: String,
value: Value
}
#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
enum Value {
Int32(i32),
Message(MessageValue)
}
// The "MessageDescriptor" will contain the information about which field is repeated etc
// Also other data which affect serialization will be included here.
// Eg {"repeated_msg": "repeated", "some_msg": "singular" ...}
#[derive(Debug, Serialize, Deserialize)]
#[serde(transparent)]
struct MessageDescriptor {
data: HashMap<String, String>
}
// One idea - to define anothe one struct "MessageValueAsJSONStructure" and then serialize it.
// But I would like to understand if there is some builtin solution like "DeserializeSeed" but for Serialize
// impl MessageDescriptor {
// fn convert_to_repeated(&self, msg: MessageValue) -> MessageValueAsJSONStructure {
// unimplemented!()
// }
// }
fn main() {
// Define the message
let msg_obj = MessageValue {
fields: vec![
FieldValue {
name: "some_int32".to_string(),
value: Value::Int32(23)
},
FieldValue {
name: "some_msg".to_string(),
value: Value::Message(MessageValue{
fields: vec![
FieldValue{name:"some_int32".to_string(), value:Value::Int32(23)},
]
})
},
FieldValue {
name: "repeated_msg".to_string(),
value: Value::Message(MessageValue{
fields: vec![
FieldValue{name:"some_int32".to_string(), value:Value::Int32(23)},
]
})
},
FieldValue {
name: "repeated_msg".to_string(),
value: Value::Message(MessageValue{
fields: vec![
FieldValue{name: "some_int32".to_string(), value: Value::Int32(27)},
FieldValue{name: "some_int32".to_string(), value: Value::Int32(29)},
]
})
},
]
};
let msg_ser = serde_json::to_string(&msg_obj).expect("Serialize the Message");
println!("OUTPUT: {:?}", msg_ser);
}
Output:
[
{
"name": "some_int32",
"value": 23
},
{
"name": "some_msg",
"value": [
{
"name": "some_int32",
"value": 23
}
]
},
{
"name": "repeated_msg",
"value": [
{
"name": "some_int32",
"value": 23
}
]
},
{
"name": "repeated_msg",
"value": [
{
"name": "some_int32",
"value": 27
},
{
"name": "other_int32",
"value": 29
}
]
}
]
Desired OUTPUT:
{
"some_int32": 23,
"some_msg": {
"some_int32": 23
},
"repeated_msg": [
{
"some_int32": 23
},
{
"some_int32": 27,
"other_int32": 29
}
]
}
Errors:
Compiling playground v0.0.1 (/playground)
Finished dev [unoptimized + debuginfo] target(s) in 1.34s
Running `target/debug/playground`