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}