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

How to unmarshal a string or a struct value? #338

Open
livingsilver94 opened this issue Dec 27, 2022 · 2 comments
Open

How to unmarshal a string or a struct value? #338

livingsilver94 opened this issue Dec 27, 2022 · 2 comments
Labels
question Further information is requested

Comments

@livingsilver94
Copy link

For example, take a look at docker-compose file. build can be a string or a struct, and that's perfectly valid. To unmarshal such a situtation, I thought I could try to unmarshal a string before, and then a struct if the former errored out. Unfortunately I found out that TypeError exists, but it's internal:

https://github.com/goccy/go-yaml/blob/v1.9.8/internal/errors/error.go#L225

Could you expose it, or suggest me an alternative way to unmarshal a value which may be of two different types?

@goccy goccy added the question Further information is requested label Nov 2, 2024
@fstamour
Copy link

I would also like to know, I have the exact same situation

@fstamour
Copy link

I managed to parse my stuff correctly using a struct with 2 fields: one string and one struct.

Then I implemented the InterfaceUnmarshaler interface for it, something like that (ironically, #446 was pretty much the documentation I was missing to understand how to do this):

type A {
  Name string
}

type Data struct {
  A A
  B string
}

func (data *Data) UnmarshalYAML(unmarshal func(interface{}) error) error {
        // Try to unmarshal as a string
	errUnmarshalAsString := unmarshal(&data.B)
	if errUnmarshalAsString == nil {
		// Success
		return nil
	}

	// Try to unmarshal as a map
	errUnmarshalAsStruct := unmarshal(&data.A)
	if errUnmarshalAsStruct != nil {
		// Both tries failed
		err := fmt.Errorf("Failed to unmarshal \"data\" as either a string or as struct A:\n %w\n %w\n",
			errUnmarshalAsString, errUnmarshalAsStruct)
		log.Print(err)
		return err
	}

	// Success
	return nil
}

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

No branches or pull requests

3 participants