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

Add InterfaceCustomUnmarshaler #449

Open
ozraru opened this issue May 11, 2024 · 0 comments · May be fixed by #450
Open

Add InterfaceCustomUnmarshaler #449

ozraru opened this issue May 11, 2024 · 0 comments · May be fixed by #450

Comments

@ozraru
Copy link
Contributor

ozraru commented May 11, 2024

Is your feature request related to a problem? Please describe.
I want to make an unmarshaler of the interface.
The interface includes several structs. And it can be identified with type field.
I've tried to make CustomUnmarshaler, but there is no CustomUnmarshaler which have the same function as InterfaceUnmarshaler.

Describe the solution you'd like
Add
func CustomInterfaceUnmarshaler[T any](unmarshaler func(*T, func(interface{}) error) error) DecodeOption
func RegisterCustomInterfaceUnmarshaler[T any](unmarshaler func(*T, func(interface{}) error) error)

Describe alternatives you've considered
I've tried to implement InterfaceUnmarshaler, but the interface cannot have function.

Additional context

Example to use
type MyInterface interface {
	foo()
}

type MyStruct1 struct {
	UniqueField1 string
}

func (m *MyStruct1) foo() {}

type MyStruct2 struct {
	UniqueField2 string
}

func (m *MyStruct2) foo() {}

type MyStruct3 struct {
	UniqueField3 string
}

func (m *MyStruct3) foo() {}

func init() {
	yaml.RegisterCustomInterfaceUnmarshaler[MyInterface](func(s *MyInterface, unmarshal func(interface{}) error) error {
		var typeSchema struct {
			Type string `json:"type"`
		}
		if err := unmarshal(&typeSchema); err != nil {
			return err
		}
		switch typeSchema.Type {
		case "str1":
			str1 := MyStruct1{}
			if err := unmarshal(&str1); err != nil {
				return err
			}
			*s = &str1
			return nil
		case "str2":
			str2 := MyStruct1{}
			if err := unmarshal(&str2); err != nil {
				return err
			}
			*s = &str2
			return nil
		case "str3":
			str3 := MyStruct1{}
			if err := unmarshal(&str3); err != nil {
				return err
			}
			*s = &str3
			return nil
		default:
			return ErrInvalidType
		}
	})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants