I have a struct in c++11 , like:
struct objectv1 {
matrix<float, 0, 1 > obj_descriptor;
string person_name;
matrix<rgb_pixel> p_obj_chip;
string notes;
};
and than:
std::vector<objectv1> object_deteails;
and pushing back to object_details data.
How can I serialize and deserialize the object_details vector?
It could be helpfull for beginners like me
Thanks
Related
This question already has answers here:
How can I support an unknown or other value for a Serde enum?
(4 answers)
Closed 2 years ago.
I'm deserializing a tagged enum:
#[derive(Deserialize)]
enum Foo {
A(A),
B(B),
C(C),
}
If Serde encounters a tag that isn't A, B or C, then it will throw an error. Is there any way to add a catch-all variant for unknown tags? I'd be happy if it only records the tag:
#[derive(Deserialize)]
enum Foo {
A(A),
B(B),
C(C),
#[serde(unknown_tag)]
Unknown(String),
}
You can use an untagged enum for this. The details depend on what you want to do exactly. The idea is to wrap Foo into a MaybeFoo, where MaybeFoo has a "universal" type to deserialize into as the second choice.
In the example below, we use a serde_json::Value as a dummy-type, as its implementation of Deserialize is universal as can deserialize anything that is valid JSON. If your source format is different, you may need a different deserializer or implement Deserialize yourself.
#[derive(serde::Deserialize, serde::Serialize, PartialEq, Debug)]
enum Foo {
A(u64),
B(f32),
C(String),
}
// MaybeFoo is untagged, which also means it "looks" exactly
// like a Foo when serialized/deserialized.
#[derive(serde::Deserialize, PartialEq, Debug)]
#[serde(untagged)]
enum MaybeFoo {
Foo(Foo),
Other(serde_json::Value)
}
The MaybeFoo is an "untagged" enum and Serde will try to deserialize MaybeFoo as a Foo and - if that fails - as serde_json::Value which will always succeed (if sourced from JSON).
fn main() {
// Lets create a Foo and serialize it
let foo = Foo::B(0.0);
let foo_json = serde_json::to_string(&foo).unwrap();
println!("{}", &foo_json);
// Deserialize works as expected
let foo_json = "{\"B\":0.0}";
assert!(serde_json::from_str::<Foo>(&foo_json).unwrap() == foo);
// Deserializing as a `MaybeFoo` works as expected
assert!(serde_json::from_str::<MaybeFoo>(&foo_json).unwrap() == MaybeFoo::Foo(foo));
// Deserializing something else is not a `Foo`!
let foo_json = "{\"Unknown\":0.0}";
let foo = serde_json::from_str::<MaybeFoo>(&foo_json).unwrap();
// Prints "Other(Object({"Unknown": Number(0.0)}))"
println!("{:?}", &foo);
}
You can use serde_json's API to inspect the unknown variant and - if it looks like a map - extract the tag. If this is your only interest, the second variant of MaybeFoo could also be a HashMap<String, serde::de::IgnoredAny>, which will deserialize any map, record the tag as a String and throw away the value. This presumes, however, that the unknown value is a tagged value.
Consider the following json representation of an object
{
"format": "0.0.1",
"has_impl": true,
"mtv_1b": 1,
"mtv_1c": "h",
"ktc_12": true,
"ktc_zz": true,
}
The first two format and has_impl fields are known. In addition, the object may have arbitrary number of mtv_XX and ktc_XX like fields.
Is such an object representable in proto3 and how would you go at it ?
The following could be an obvious starting point. Are there a combination of oneOf, WellKnownTypes that could be used here ?
message MyObject {
string format = 0;
bool has_impl = 1;
// Is there anything that can go in here ?
....
}
Not directly. The closest you can do would be to have a Struct (which is a map<string, Value>, where Value is a oneof over common types), using struct.proto. Not quite the same, but allows the same ideas.
I want to encode/decode an AST in Golang but am running up against a roadblock with the lack of sumtypes.
A very trivial AST to demonstrate the problem:
data BoolAST = Or BoolAST BoolAST | And BoolAST BoolAST | Lit Bool
Approach 1
type BoolStatement interface {
ComputeBool() bool
Serialize() []byte
}
type Or struct {
Left BoolStatement
Right BoolStatement
}
type And struct {
Left BoolStatement
Right BoolStatement
}
type BoolFunc struct {
Value bool
}
Now this structure serializes very well, But what I am having trouble with is deserializing (msgpack, json, etc). So You would have to wrap the interface in a struct so you can add a deserializer method. This to me also seems sloppy as I dont want to have to hand craft a serializer
Approach 2
To solve this I changed my struct a little bit. Everything is the same struct, but only one field is populated at a time. This code makes deserialization a breeze.
type BoolAST struct {
Or []BoolAST
And []BoolAST
Lit bool
}
This works well to deserialize because empty fields are left nil, but then I have these empty fields. When interpreting the AST I have to use switch statements to find what field is null and that adds a tiny bit of overhead.
This also makes the json nice:
{
"and": [
{"lit": true},
{"or": [
{"lit": false},
{"lit": true}}
]
]
}
But this can get crazy when the ast has many types of branching paths. You might end up with 10 nil fields on the struct.
It seems very hard with no sum types to solve this problem. Is this the right approach?
I am very new to Go and am trying to get my head around all the different types and how to use them. I have an interface with the following (which was originally in a json file):
[map[item:electricity transform:{fuelType}] map[transform:{fuelType} item:gas]]
and I have the following struct
type urlTransform struct {
item string
transform string
}
I have no idea how to get the interface data into the struct; I'm sure this is really stupid, but I have been trying all day. Any help would be greatly appreciated.
Decode the JSON directly to types you want instead of decoding to an interface{}.
Declare types that match the structure of your JSON data. Use structs for JSON objects and slices for JSON arrays:
type transform struct {
// not enough information in question to fill this in.
}
type urlTransform struct {
Item string
Transform transform
}
var transforms []urlTransform
The field names must be exported (start with uppercase letter).
Unmarshal the JSON to the declared value:
err := json.Unmarshal(data, &transforms)
or
err := json.NewDecoder(reader).Decode(&transforms)
From your response : [map[item:electricity transform:{fuelType}] map[transform:{fuelType} item:gas]].
As you can see here this is a an array that has map in it.
One way to get the value from this is :
values := yourResponse[0].(map[string]interface{}). // convert first index to map that has interface value.
transform := urlTransform{}
transform.Item = values["item"].(string) // convert the item value to string
transform.Transform = values["transform"].(string)
//and so on...
as you can see from the code above I'm getting the the value using map. And convert the value to the appropriate type in this case is string.
You can convert it to appropriate type like int or bool or other type. but this approach is painful as you need to get the value one bye one and assign it your your field struct.
So I have a question that I've been trying to figure out for a while and hopefully someone has some insight. Basically, I have two similar, but different structs in Go and I would like to convert between them.
Something like the following:
type A struct {
Name string
}
type B struct {
Name NameStruct
}
type NameStruct struct {
Firstname string
Lastname string
}
In this example,
B.Name == NameStruct{
Firstname: strings.Split(A.Name, " ")[0],
Lastname: strings.Split(A.Name, " ")[1],
}
Basically I would like to be able to define a mapping of fields from one struct to the other as well as a conversion function, so that I can do this without writing all of the code to do the conversion manually.
What I'm imagining is that there might be some sort of Go generator out there that could do something like this. I don't think it is possible using reflection because of the nested structs (although I'm open to suggestions).
Basically, does anyone know of a way to do this that is better than either writing conversion code manually or creating my own generator?