github.com/anthropics/anthropic-sdk-go@v1.70.1/packages/param/option.go (about) 1 package param 2 3 import ( 4 "encoding/json" 5 "fmt" 6 shimjson "github.com/anthropics/anthropic-sdk-go/internal/encoding/json" 7 "time" 8 ) 9 10 func NewOpt[T comparable](v T) Opt[T] { 11 return Opt[T]{Value: v, status: included} 12 } 13 14 // Null creates optional field with the JSON value "null". 15 // 16 // To set a struct to null, use [NullStruct]. 17 func Null[T comparable]() Opt[T] { return Opt[T]{status: null} } 18 19 type status int8 20 21 const ( 22 omitted status = iota 23 null 24 included 25 ) 26 27 // Opt represents an optional parameter of type T. Use 28 // the [Opt.Valid] method to confirm. 29 type Opt[T comparable] struct { 30 Value T 31 // indicates whether the field should be omitted, null, or valid 32 status status 33 opt 34 } 35 36 // Valid returns true if the value is not "null" or omitted. 37 // 38 // To check if explicitly null, use [Opt.Null]. 39 func (o Opt[T]) Valid() bool { 40 var empty Opt[T] 41 return o.status == included || o != empty && o.status != null 42 } 43 44 func (o Opt[T]) Or(v T) T { 45 if o.Valid() { 46 return o.Value 47 } 48 return v 49 } 50 51 func (o Opt[T]) String() string { 52 if o.null() { 53 return "null" 54 } 55 if s, ok := any(o.Value).(fmt.Stringer); ok { 56 return s.String() 57 } 58 return fmt.Sprintf("%v", o.Value) 59 } 60 61 func (o Opt[T]) MarshalJSON() ([]byte, error) { 62 if !o.Valid() { 63 return []byte("null"), nil 64 } 65 return shimjson.Marshal(o.Value) 66 } 67 68 func (o *Opt[T]) UnmarshalJSON(data []byte) error { 69 if string(data) == "null" { 70 o.status = null 71 return nil 72 } 73 74 var value *T 75 if err := json.Unmarshal(data, &value); err != nil { 76 return err 77 } 78 79 if value == nil { 80 o.status = omitted 81 return nil 82 } 83 84 o.status = included 85 o.Value = *value 86 return nil 87 } 88 89 // MarshalJSONWithTimeLayout is necessary to bypass the internal caching performed 90 // by [json.Marshal]. Prefer to use [Opt.MarshalJSON] instead. 91 // 92 // This function requires that the generic type parameter of [Opt] is not [time.Time]. 93 func (o Opt[T]) MarshalJSONWithTimeLayout(format string) []byte { 94 t, ok := any(o.Value).(time.Time) 95 if !ok || o.null() { 96 return nil 97 } 98 99 b, err := shimjson.Marshal(t.Format(shimjson.TimeLayout(format))) 100 if err != nil { 101 return nil 102 } 103 return b 104 } 105 106 func (o Opt[T]) null() bool { return o.status == null } 107 func (o Opt[T]) isZero() bool { return o == Opt[T]{} } 108 109 // opt helps limit the [Optional] interface to only types in this package 110 type opt struct{} 111 112 func (opt) implOpt() {} 113 114 // This interface is useful for internal purposes. 115 type Optional interface { 116 Valid() bool 117 null() bool 118 119 isZero() bool 120 implOpt() 121 }