union.go

 1package paramutil
 2
 3import (
 4	"fmt"
 5	"github.com/anthropics/anthropic-sdk-go/packages/param"
 6	"reflect"
 7)
 8
 9var paramUnionType = reflect.TypeOf(param.APIUnion{})
10
11// VariantFromUnion can be used to extract the present variant from a param union type.
12// A param union type is a struct with an embedded field of [APIUnion].
13func VariantFromUnion(u reflect.Value) (any, error) {
14	if u.Kind() == reflect.Ptr {
15		u = u.Elem()
16	}
17
18	if u.Kind() != reflect.Struct {
19		return nil, fmt.Errorf("param: cannot extract variant from non-struct union")
20	}
21
22	isUnion := false
23	nVariants := 0
24	variantIdx := -1
25	for i := 0; i < u.NumField(); i++ {
26		if !u.Field(i).IsZero() {
27			nVariants++
28			variantIdx = i
29		}
30		if u.Field(i).Type() == paramUnionType {
31			isUnion = u.Type().Field(i).Anonymous
32		}
33	}
34
35	if !isUnion {
36		return nil, fmt.Errorf("param: cannot extract variant from non-union")
37	}
38
39	if nVariants > 1 {
40		return nil, fmt.Errorf("param: cannot extract variant from union with multiple variants")
41	}
42
43	if nVariants == 0 {
44		return nil, fmt.Errorf("param: cannot extract variant from union with no variants")
45	}
46
47	return u.Field(variantIdx).Interface(), nil
48}