Skip to content
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

[BUG] Encoding of nested struct is missing named prefix #228

Open
1 task done
gKits opened this issue Nov 27, 2024 · 2 comments · May be fixed by #229
Open
1 task done

[BUG] Encoding of nested struct is missing named prefix #228

gKits opened this issue Nov 27, 2024 · 2 comments · May be fixed by #229
Labels

Comments

@gKits
Copy link

gKits commented Nov 27, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

I have the two following structs:

type Foo struct {
	X string `schema:"x"`
	Y Bar    `schema:"y"`
}

type Bar struct {
	A string `schema:"a"`
	B bool   `schema:"b"`
}

If I encode a variable f1 of Foo into some values and I try to decode said values again into another Foo f2 the values are not the same and Decode returns and error schema: invalid path "a" (and 1 other error).

f := Foo{
	X: "test",
	Y: Bar{
		A: "test",
		B: true,
	},
}

vals := map[string][]string{}
if err := schema.NewEncoder().Encode(f, vals); err != nil { // This does not fail
	panic(err)
}
// vals = map[a:[test] b:[true] x:[test]]

var f2 Foo
if err := schema.NewDecoder().Decode(&f2, vals); err != nil { // This fails
	panic(err) // panic: schema: invalid path "a" (and 1 other error)
}

This problem appears to only occur with nested structs and probably comes from the fact that Decode requires prefixes for nested values separated with a . and Encode does not add these said prefixes.

vals = map[string][]string{
    "x":   {"hello"},
    "y.a": {"world"},
    "y.b": {"true"},
}
var f3 Foo
if err := schema.NewDecoder().Decode(&f3, vals); err != nil { // This works just fine
    panic(err)
}
// f3 = {hello {world true}}

Expected Behavior

It should be possible to decode the values that have been encoded with the same library. Therefore Encode should add the period separated prefixes to fields of nested structs.

f := Foo{
    X: "hello",
    Y: Bar{
        A: "world",
        B: true,
    },
}

vals := map[string][]string{}
if err := schema.NewEncoder().Encode(f, vals); err != nil { // This should not fail
    panic(err)
}
// Should result into 
// vals = map[y.a:[test] y.b:[true] x:[test]]

Steps To Reproduce

Run the following code:

package main

import  "github.com/gorilla/schema"

func main() {
	f := Foo{
		X: "test",
		Y: Bar{
			A: "test",
			B: true,
		},
	}

	vals := map[string][]string{}
	if err := schema.NewEncoder().Encode(f, vals); err != nil { // This does not fail
		panic(err)
	}
	// vals = map[a:[test] b:[true] x:[test]]

	var f2 Foo
	if err := schema.NewDecoder().Decode(&f2, vals); err != nil { // This fails
		panic(err) // panic: schema: invalid path "a" (and 1 other error)
	}
}

Anything else?

No response

@gKits gKits added the bug label Nov 27, 2024
@gKits gKits linked a pull request Nov 28, 2024 that will close this issue
12 tasks
@gKits
Copy link
Author

gKits commented Nov 28, 2024

I have created a PR that adds a method ActivateKeySeparation to the Encoder which allows the Encoder to appends the name of each nested struct field to the full key inside the values map. Though I am not sure about the name of the method. Any other suggestions?

@zak905
Copy link
Contributor

zak905 commented Nov 28, 2024

Hi @gKits, nice catch, this would be a nice addition.

@jaitaiwan, do you mind taking a look ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants