github.com/anthropics/anthropic-sdk-go@v1.70.1/internal/paramutil/union.go (about)

     1  package paramutil
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/anthropics/anthropic-sdk-go/packages/param"
     6  	"reflect"
     7  )
     8  
     9  var 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].
    13  func 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  }