Skip to content

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

Open
@gKits

Description

@gKits

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions