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

Unmarshal methods does not work with embedded structures #1050

Closed
toby3d opened this issue Dec 17, 2020 · 4 comments
Closed

Unmarshal methods does not work with embedded structures #1050

toby3d opened this issue Dec 17, 2020 · 4 comments
Labels
kind/support Support requests for using the project

Comments

@toby3d
Copy link

toby3d commented Dec 17, 2020

Expected behavior (what you expected to happen):

(syndication.Config) {
	Target: (syndication.Target) {
		UID: (string) "https://mstdn.io/@toby3d",
		Name: (string) "toby3d@mstdn.io",
		Service: (*syndication.Details) {
			Name: (string) "Mastodon",
			URL: (string) "https://mstdn.io/"
		},
		User: (*syndication.Details) {
			Name: (string) "toby3d@mstdn.io",
			URL: (string) "https://mstdn.io/@toby3d"
		}
	},
	Client: (syndication.Client) {
		ID: (string) (len=43) "hackme",
		Secret: (string) (len=43) "hackmetwice"
	}
}

Actual behavior (what actually happened):

(syndication.Config) {
	Target: (syndication.Target) {
		UID: (string) "",
		Name: (string) "",
		Service: (*syndication.Details) (nil),
		User: (*syndication.Details) (nil)
	},
	Client: (syndication.Client) {
		ID: (string) (len=43) "hackme",
		Secret: (string) (len=43) "hackmetwice"
	}
}

Repl.it link: https://repl.it/@toby3d/viper#main_test.go

Code reproducing the issue:

package debug_test

import (
	"io/ioutil"
	"os"
	"testing"

	"github.com/spf13/viper"
	"github.com/stretchr/testify/assert"
)

type (
	Syndication struct {
		Target Target `yaml:",inline"` // NOTE(toby3d): why nil?
		Client Client `yaml:"client"`
	}

	Client struct {
		ID     string `yaml:"id"`
		Secret string `yaml:"secret"`
	}

	Target struct {
		UID     string   `yaml:"uid" json:"uid"`
		Name    string   `yaml:"name" json:"name"`
		Service *Details `yaml:"service,omitempty" json:"service,omitempty"`
		User    *Details `yaml:"user,omitempty" json:"user,omitempty"`
	}

	Details struct {
		Name  string `yaml:"name" json:"name"`
		URL   string `yaml:"url,omitempty" json:"url,omitempty"`
		Photo string `yaml:"photo,omitempty" json:"photo,omitempty"`
	}
)

const raw = `---
baseURL: https://toby3d.test/
silos:
  - uid: https://mstdn.io/@toby3d
    name: toby3d@mstdn.io
    user:
      name: "toby3d@mstdn.io"
      url: "https://mstdn.io/@toby3d"
    service:
      name: Mastodon
      url: https://mstdn.io/
    client:
      id: hackme
      secret: hackmetwice
`

func TestRead(t *testing.T) {
	assert := assert.New(t)

	f, err := ioutil.TempFile(os.TempDir(), "config.*.yaml")
	if !assert.NoError(err) {
		t.FailNow()
	}
	defer f.Close()
	f.WriteString(raw)

	v := viper.New()
	v.AddConfigPath(os.TempDir())
	v.SetConfigFile(f.Name())
	if !assert.NoError(v.ReadInConfig()) {
		t.FailNow()
	}

	silos := make([]Syndication, 0)
	if !assert.NoError(v.UnmarshalKey("silos", &silos)) {
		t.FailNow()
	}

	assert.Contains(silos, Syndication{
		Target: Target{
			UID:  "https://mstdn.io/@toby3d",
			Name: "toby3d@mstdn.io",
			Service: &Details{
				Name: "Mastodon",
				URL:  "https://mstdn.io/",
			},
			User: &Details{
				Name: "toby3d@mstdn.io",
				URL:  "https://mstdn.io/@toby3d",
			},
		},
		Client: Client{
			ID:     "hackme",
			Secret: "hackmetwice",
		},
	})
}

Environment:

  • Viper version: v1.7.1
  • Config source: file
  • File format: YAML
@toby3d toby3d added the kind/bug Something isn't working label Dec 17, 2020
@github-actions
Copy link

👋 Thanks for reporting!

A maintainer will take a look at your issue shortly. 👀

In the meantime: We are working on Viper v2 and we would love to hear your thoughts about what you like or don't like about Viper, so we can improve or fix those issues.

⏰ If you have a couple minutes, please take some time and share your thoughts: https://forms.gle/R6faU74qPRPAzchZ9

📣 If you've already given us your feedback, you can still help by spreading the news,
either by sharing the above link or telling people about this on Twitter:

https://twitter.com/sagikazarmark/status/1306904078967074816

Thank you! ❤️

@toby3d
Copy link
Author

toby3d commented Dec 17, 2020

To decode the keys into an embedded structure, I used the yaml:",inline" tag from the documentation package for YAML that Viper uses: https://pkg.go.dev/gopkg.in/yaml.v2#example-Unmarshal-Embedded

@sagikazarmark sagikazarmark added kind/support Support requests for using the project and removed kind/bug Something isn't working labels Dec 17, 2020
@sagikazarmark
Copy link
Collaborator

Unfortunately, that doesn't work with mapstructure (the library used under the hood). You need to use mapstructure tag with ,squash.

@sagikazarmark
Copy link
Collaborator

Although this is explicitly mentioned in the documentation, I added a troubleshooting section to the readme: https://github.com/spf13/viper#unmarshaling-doesnt-work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/support Support requests for using the project
Projects
None yet
Development

No branches or pull requests

2 participants