1 // Copyright 2016 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package optional provides versions of primitive types that can 16 // be nil. These are useful in methods that update some of an API object's 17 // fields. 18 package optional 19 20 import ( 21 "fmt" 22 "strings" 23 "time" 24 ) 25 26 type ( 27 // Bool is either a bool or nil. 28 Bool interface{} 29 30 // String is either a string or nil. 31 String interface{} 32 33 // Int is either an int or nil. 34 Int interface{} 35 36 // Uint is either a uint or nil. 37 Uint interface{} 38 39 // Float64 is either a float64 or nil. 40 Float64 interface{} 41 42 // Duration is either a time.Duration or nil. 43 Duration interface{} 44 ) 45 46 // ToBool returns its argument as a bool. 47 // It panics if its argument is nil or not a bool. 48 func ToBool(v Bool) bool { 49 x, ok := v.(bool) 50 if !ok { 51 doPanic("Bool", v) 52 } 53 return x 54 } 55 56 // ToString returns its argument as a string. 57 // It panics if its argument is nil or not a string. 58 func ToString(v String) string { 59 x, ok := v.(string) 60 if !ok { 61 doPanic("String", v) 62 } 63 return x 64 } 65 66 // ToInt returns its argument as an int. 67 // It panics if its argument is nil or not an int. 68 func ToInt(v Int) int { 69 x, ok := v.(int) 70 if !ok { 71 doPanic("Int", v) 72 } 73 return x 74 } 75 76 // ToUint returns its argument as a uint. 77 // It panics if its argument is nil or not a uint. 78 func ToUint(v Uint) uint { 79 x, ok := v.(uint) 80 if !ok { 81 doPanic("Uint", v) 82 } 83 return x 84 } 85 86 // ToFloat64 returns its argument as a float64. 87 // It panics if its argument is nil or not a float64. 88 func ToFloat64(v Float64) float64 { 89 x, ok := v.(float64) 90 if !ok { 91 doPanic("Float64", v) 92 } 93 return x 94 } 95 96 // ToDuration returns its argument as a time.Duration. 97 // It panics if its argument is nil or not a time.Duration. 98 func ToDuration(v Duration) time.Duration { 99 x, ok := v.(time.Duration) 100 if !ok { 101 doPanic("Duration", v) 102 } 103 return x 104 } 105 106 func doPanic(capType string, v interface{}) { 107 panic(fmt.Sprintf("optional.%s value should be %s, got %T", capType, strings.ToLower(capType), v)) 108 } 109