-
Notifications
You must be signed in to change notification settings - Fork 292
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
cue: EncodeType doesn't unify embedded Go struct marked with a json inline tag with struct definition #1772
Comments
Nice find! This does indeed look like a bug with the Go-to-CUE type conversion logic.
This prints the following on my machine (with CUE v0.4.3):
|
…truct definition Signed-off-by: Clare Yang (zhanyang) <zhanyang@cisco.com>
…nition This actually fixes a bug in GoTypeToExpr under internal/core/convert, it doesn't unify embedded Go struct with struct definition, and add two test cases to verify this fix working well. Fixes: cue-lang#1772 Signed-off-by: Clare Yang (zhanyang) <zhanyang@cisco.com>
I ran into this today, using structs from a 3rd party package. My workaround was to create local versions of those structs, with the added Are there any updates on the issue? I'm working on something that could expose this to end users, which would be a potential stoppper... |
After more testing I realised the 3rd party structs I was using had nested embedding on quite some levels... Hence I wrote a hacky little function to unify embedded structs with it's parent. This might be helpful for others coming here who want a hacky fix: func cueRemoveEmbeddedAnomaly(val cue.Value) (cue.Value, error) {
iter, err := val.Fields(cue.All())
if err != nil {
return val, err
}
newVal := val.Context().CompileString("{}")
for iter.Next() {
field := iter.Value()
fieldPath := cue.MakePath(iter.Selector())
label, ok := field.Label()
if !ok {
continue
}
if field.Kind() != cue.StructKind {
newVal = newVal.FillPath(fieldPath, field)
continue
}
child, err := cueRemoveEmbeddedAnomaly(field)
if err != nil {
return val, err
}
if label == "" {
newVal = newVal.Unify(child)
continue
}
newVal = newVal.FillPath(fieldPath, child)
}
return newVal, nil
} Now if you run your test like this, it should give the desired output: func TestEncodeTypeWithEmbeddedHack(t *testing.T) {
type Hello struct {
Hello string `json:"hello"`
}
type Example struct {
Hello
}
ctx := cuecontext.New()
val := ctx.EncodeType(Example{})
val, err := cueRemoveEmbeddedAnomaly(val)
if err != nil {
t.Fatal(err)
}
node := val.Syntax()
raw, _ := format.Node(node)
fmt.Printf("-- gotype.cue --\n%s\n", raw)
data, _ := json.Marshal(Example{
Hello: Hello{"one"},
})
fmt.Printf("-- gotype.json --\n%s\n", data)
} |
What version of CUE are you using (
cue version
)?Does this issue reproduce with the latest release?
Yes
What did you do?
When did convert a Go type to CUE value via
EncodeType
, embedded Go struct marked with a json inline tag doesn't unify with struct definition, an empty CUE field will map to CUE value of embedded Go struct.Reproduce this via below code:
What did you expect to see?
What did you see instead?
The text was updated successfully, but these errors were encountered: