github.com/searKing/golang/go@v1.2.117/exp/types/optional.go (about) 1 // Copyright 2023 The searKing Author. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package types 6 7 import ( 8 "cmp" 9 "fmt" 10 "io" 11 "reflect" 12 ) 13 14 // Optional represents a Value that may be null. 15 type Optional[E any] struct { 16 Value E 17 Valid bool // Valid is true if Value is not NULL 18 } 19 20 func (o Optional[E]) Format(s fmt.State, verb rune) { 21 if o.Valid { 22 _, _ = fmt.Fprintf(s, "%"+string(verb), o.Value) 23 return 24 } 25 switch verb { 26 case 'v': 27 if s.Flag('+') { 28 _, _ = fmt.Fprintf(s, "null %s: %+v", reflect.TypeOf(o.Value).String(), o.Value) 29 return 30 } 31 fallthrough 32 case 's', 'q': 33 _, _ = io.WriteString(s, "null") 34 } 35 } 36 37 func (o Optional[E]) String() string { 38 if o.Valid { 39 return fmt.Sprintf("%v", o.Value) 40 } 41 return "null" 42 } 43 44 // ValueOr returns the contained value if available, another value otherwise 45 func (o Optional[E]) ValueOr(e E) E { 46 if o.Valid { 47 return o.Value 48 } 49 return e 50 } 51 52 func CompareOptional[E cmp.Ordered](a, b Optional[E]) int { 53 if a.Valid && !b.Valid { 54 return 1 55 } 56 if !a.Valid && b.Valid { 57 return -1 58 } 59 if !a.Valid && !b.Valid { 60 return 0 61 } 62 63 if a.Value == b.Value { 64 return 0 65 } 66 if a.Value < b.Value { 67 return -1 68 } 69 return 1 70 } 71 72 func Opt[E any](e E) Optional[E] { 73 return Optional[E]{ 74 Value: e, 75 Valid: true, 76 } 77 } 78 79 // NullOpt is the null Optional. 80 // 81 // Deprecated: Use a literal types.Optional[E]{} instead. 82 func NullOpt[E any]() Optional[E] { 83 var zeroE E 84 return Optional[E]{ 85 Value: zeroE, 86 Valid: false, 87 } 88 }