-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feature: support deserializing registered CBOR tag to an interface type #301
Comments
Thanks for reporting this. The decoder needs to know the specific Go type that implements the interface to decode to. One workaround is to make this change:
This scenario is interesting because CBOR data contains a tag number which decoder might be able to use to create an object without any other hint. To determine if supporting this (without the workaround) is feasible, I'll need to look into it. Please let me know if the workaround resolves this issue for you. https://go.dev/play/p/i6EszRImp2__b
|
Well, the problem is that with your workaround, I loose the main point : decoding an unknown struct bound by an interface. type Task interface {
Do()
}
type MoveTask struct {
// omitted
}
// MoveTask impl Task
type SingTask struct {
// omitted
}
// SingTask impl Task
type Tasks struct {
Tasks []Task
} I can encode but not decode : data, _ := encMode.Marshal(Tasks{Tasks: []Task{MoveTask{}, SingTask{}}})
var tasks Tasks // I can't specify the type more than that
err = decMode.Unmarshal(data, &tasks)
if err != nil {
panic(err)
}
fmt.Println(orig) Usually, libraries that support this add a discriminator (manually or automatically defined) to the serialized objects that identify the type. I tought that it was the intent of CBOR tags since I also specify the Go type, but it apparently isn't. Also, another surprising bit. If I relieve the interface constraint like that : type Task struct {
Tasks []interface{}
} It is now able to decode each struct in the slice properly (given I define a CBOR tag for each struct). |
Yes, I agree the workaround isn't exactly the same as what you were trying to do. The difference in behavior you describe is because the decoder takes two different paths depending on the type being decoded to:
Thanks for going into more detail. I'll try to make time to look into it. It seems a worthwhile improvement. 👍 |
@Gui-Yom I'll implement and include this feature in the next release. |
What version of fxamacker/cbor are you using?
2.3.0
Does this issue reproduce with the latest release?
What OS and CPU architecture are you using (
go env
)?go env
OutputWhat did you do?
This code prints an err at the Unmarshal step.
I either do not understand how to use this library or there is a bug somewhere.
What did you expect to see?
Not a panic. Unmarshal should be working.
What did you see instead?
If I define the interface B like that instead :
B becomes an alias to interface{} and then Unmarshal works, correctly reading the cbor tag.
The text was updated successfully, but these errors were encountered: