registry.go 955 B

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. package apijson
  2. import (
  3. "reflect"
  4. "github.com/tidwall/gjson"
  5. )
  6. type UnionVariant struct {
  7. TypeFilter gjson.Type
  8. DiscriminatorValue interface{}
  9. Type reflect.Type
  10. }
  11. var unionRegistry = map[reflect.Type]unionEntry{}
  12. var unionVariants = map[reflect.Type]interface{}{}
  13. type unionEntry struct {
  14. discriminatorKey string
  15. variants []UnionVariant
  16. }
  17. func RegisterUnion(typ reflect.Type, discriminator string, variants ...UnionVariant) {
  18. unionRegistry[typ] = unionEntry{
  19. discriminatorKey: discriminator,
  20. variants: variants,
  21. }
  22. for _, variant := range variants {
  23. unionVariants[variant.Type] = typ
  24. }
  25. }
  26. // Useful to wrap a union type to force it to use [apijson.UnmarshalJSON] since you cannot define an
  27. // UnmarshalJSON function on the interface itself.
  28. type UnionUnmarshaler[T any] struct {
  29. Value T
  30. }
  31. func (c *UnionUnmarshaler[T]) UnmarshalJSON(buf []byte) error {
  32. return UnmarshalRoot(buf, &c.Value)
  33. }