1 package ldvalue 2 3 // OptionalBool represents a bool that may or may not have a value. This is similar to using a 4 // bool pointer to distinguish between a false value and nil, but it is safer because it does not 5 // expose a pointer to any mutable value. 6 // 7 // To create an instance with a bool value, use [NewOptionalBool]. There is no corresponding method 8 // for creating an instance with no value; simply use the empty literal OptionalBool{}. 9 // 10 // ob1 := NewOptionalBool(1) 11 // ob2 := NewOptionalBool(false) // this has a value which is false 12 // ob3 := OptionalBool{} // this does not have a value 13 // 14 // This can also be used as a convenient way to construct a bool pointer within an expression. 15 // For instance, this example causes myIntPointer to point to the bool value true: 16 // 17 // var myBoolPointer *int = NewOptionalBool(true).AsPointer() 18 // 19 // The reason LaunchDarkly code uses this specific type instead of a generic Optional[T] is for 20 // efficiency in JSON marshaling/unmarshaling. A generic type would have to use reflection and 21 // dynamic typecasting for its marshal/unmarshal methods. 22 type OptionalBool struct { 23 optValue optional[bool] 24 } 25 26 // NewOptionalBool constructs an OptionalBool that has a bool value. 27 // 28 // There is no corresponding method for creating an OptionalBool with no value; simply use the 29 // empty literal OptionalBool{}. 30 func NewOptionalBool(value bool) OptionalBool { 31 return OptionalBool{optValue: newOptional(value)} 32 } 33 34 // NewOptionalBoolFromPointer constructs an OptionalBool from a bool pointer. If the pointer is 35 // non-nil, then the OptionalBool copies its value; otherwise the OptionalBool has no value. 36 func NewOptionalBoolFromPointer(valuePointer *bool) OptionalBool { 37 return OptionalBool{optValue: newOptionalFromPointer(valuePointer)} 38 } 39 40 // IsDefined returns true if the OptionalBool contains a bool value, or false if it has no value. 41 func (o OptionalBool) IsDefined() bool { 42 return o.optValue.isDefined() 43 } 44 45 // BoolValue returns the OptionalBool's value, or false if it has no value. 46 func (o OptionalBool) BoolValue() bool { 47 return o.optValue.getOrZeroValue() 48 } 49 50 // Get is a combination of BoolValue and IsDefined. If the OptionalBool contains a bool value, it 51 // returns that value and true; otherwise it returns false and false. 52 func (o OptionalBool) Get() (bool, bool) { 53 return o.optValue.get() 54 } 55 56 // OrElse returns the OptionalBool's value if it has one, or else the specified fallback value. 57 func (o OptionalBool) OrElse(valueIfEmpty bool) bool { 58 return o.optValue.getOrElse(valueIfEmpty) 59 } 60 61 // AsPointer returns the OptionalBool's value as a bool pointer if it has a value, or nil 62 // otherwise. 63 // 64 // The bool value, if any, is copied rather than returning to a pointer to the internal field. 65 func (o OptionalBool) AsPointer() *bool { 66 return o.optValue.getAsPointer() 67 } 68 69 // AsValue converts the OptionalBool to a [Value], which is either [Null]() or a boolean value. 70 func (o OptionalBool) AsValue() Value { 71 if value, ok := o.optValue.get(); ok { 72 return Bool(value) 73 } 74 return Null() 75 } 76