value.go (6505B)
1 // Copyright The OpenTelemetry Authors 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 attribute // import "go.opentelemetry.io/otel/attribute" 16 17 import ( 18 "encoding/json" 19 "fmt" 20 "reflect" 21 "strconv" 22 23 "go.opentelemetry.io/otel/internal" 24 "go.opentelemetry.io/otel/internal/attribute" 25 ) 26 27 //go:generate stringer -type=Type 28 29 // Type describes the type of the data Value holds. 30 type Type int // nolint: revive // redefines builtin Type. 31 32 // Value represents the value part in key-value pairs. 33 type Value struct { 34 vtype Type 35 numeric uint64 36 stringly string 37 slice interface{} 38 } 39 40 const ( 41 // INVALID is used for a Value with no value set. 42 INVALID Type = iota 43 // BOOL is a boolean Type Value. 44 BOOL 45 // INT64 is a 64-bit signed integral Type Value. 46 INT64 47 // FLOAT64 is a 64-bit floating point Type Value. 48 FLOAT64 49 // STRING is a string Type Value. 50 STRING 51 // BOOLSLICE is a slice of booleans Type Value. 52 BOOLSLICE 53 // INT64SLICE is a slice of 64-bit signed integral numbers Type Value. 54 INT64SLICE 55 // FLOAT64SLICE is a slice of 64-bit floating point numbers Type Value. 56 FLOAT64SLICE 57 // STRINGSLICE is a slice of strings Type Value. 58 STRINGSLICE 59 ) 60 61 // BoolValue creates a BOOL Value. 62 func BoolValue(v bool) Value { 63 return Value{ 64 vtype: BOOL, 65 numeric: internal.BoolToRaw(v), 66 } 67 } 68 69 // BoolSliceValue creates a BOOLSLICE Value. 70 func BoolSliceValue(v []bool) Value { 71 return Value{vtype: BOOLSLICE, slice: attribute.BoolSliceValue(v)} 72 } 73 74 // IntValue creates an INT64 Value. 75 func IntValue(v int) Value { 76 return Int64Value(int64(v)) 77 } 78 79 // IntSliceValue creates an INTSLICE Value. 80 func IntSliceValue(v []int) Value { 81 var int64Val int64 82 cp := reflect.New(reflect.ArrayOf(len(v), reflect.TypeOf(int64Val))) 83 for i, val := range v { 84 cp.Elem().Index(i).SetInt(int64(val)) 85 } 86 return Value{ 87 vtype: INT64SLICE, 88 slice: cp.Elem().Interface(), 89 } 90 } 91 92 // Int64Value creates an INT64 Value. 93 func Int64Value(v int64) Value { 94 return Value{ 95 vtype: INT64, 96 numeric: internal.Int64ToRaw(v), 97 } 98 } 99 100 // Int64SliceValue creates an INT64SLICE Value. 101 func Int64SliceValue(v []int64) Value { 102 return Value{vtype: INT64SLICE, slice: attribute.Int64SliceValue(v)} 103 } 104 105 // Float64Value creates a FLOAT64 Value. 106 func Float64Value(v float64) Value { 107 return Value{ 108 vtype: FLOAT64, 109 numeric: internal.Float64ToRaw(v), 110 } 111 } 112 113 // Float64SliceValue creates a FLOAT64SLICE Value. 114 func Float64SliceValue(v []float64) Value { 115 return Value{vtype: FLOAT64SLICE, slice: attribute.Float64SliceValue(v)} 116 } 117 118 // StringValue creates a STRING Value. 119 func StringValue(v string) Value { 120 return Value{ 121 vtype: STRING, 122 stringly: v, 123 } 124 } 125 126 // StringSliceValue creates a STRINGSLICE Value. 127 func StringSliceValue(v []string) Value { 128 return Value{vtype: STRINGSLICE, slice: attribute.StringSliceValue(v)} 129 } 130 131 // Type returns a type of the Value. 132 func (v Value) Type() Type { 133 return v.vtype 134 } 135 136 // AsBool returns the bool value. Make sure that the Value's type is 137 // BOOL. 138 func (v Value) AsBool() bool { 139 return internal.RawToBool(v.numeric) 140 } 141 142 // AsBoolSlice returns the []bool value. Make sure that the Value's type is 143 // BOOLSLICE. 144 func (v Value) AsBoolSlice() []bool { 145 if v.vtype != BOOLSLICE { 146 return nil 147 } 148 return v.asBoolSlice() 149 } 150 151 func (v Value) asBoolSlice() []bool { 152 return attribute.AsBoolSlice(v.slice) 153 } 154 155 // AsInt64 returns the int64 value. Make sure that the Value's type is 156 // INT64. 157 func (v Value) AsInt64() int64 { 158 return internal.RawToInt64(v.numeric) 159 } 160 161 // AsInt64Slice returns the []int64 value. Make sure that the Value's type is 162 // INT64SLICE. 163 func (v Value) AsInt64Slice() []int64 { 164 if v.vtype != INT64SLICE { 165 return nil 166 } 167 return v.asInt64Slice() 168 } 169 170 func (v Value) asInt64Slice() []int64 { 171 return attribute.AsInt64Slice(v.slice) 172 } 173 174 // AsFloat64 returns the float64 value. Make sure that the Value's 175 // type is FLOAT64. 176 func (v Value) AsFloat64() float64 { 177 return internal.RawToFloat64(v.numeric) 178 } 179 180 // AsFloat64Slice returns the []float64 value. Make sure that the Value's type is 181 // FLOAT64SLICE. 182 func (v Value) AsFloat64Slice() []float64 { 183 if v.vtype != FLOAT64SLICE { 184 return nil 185 } 186 return v.asFloat64Slice() 187 } 188 189 func (v Value) asFloat64Slice() []float64 { 190 return attribute.AsFloat64Slice(v.slice) 191 } 192 193 // AsString returns the string value. Make sure that the Value's type 194 // is STRING. 195 func (v Value) AsString() string { 196 return v.stringly 197 } 198 199 // AsStringSlice returns the []string value. Make sure that the Value's type is 200 // STRINGSLICE. 201 func (v Value) AsStringSlice() []string { 202 if v.vtype != STRINGSLICE { 203 return nil 204 } 205 return v.asStringSlice() 206 } 207 208 func (v Value) asStringSlice() []string { 209 return attribute.AsStringSlice(v.slice) 210 } 211 212 type unknownValueType struct{} 213 214 // AsInterface returns Value's data as interface{}. 215 func (v Value) AsInterface() interface{} { 216 switch v.Type() { 217 case BOOL: 218 return v.AsBool() 219 case BOOLSLICE: 220 return v.asBoolSlice() 221 case INT64: 222 return v.AsInt64() 223 case INT64SLICE: 224 return v.asInt64Slice() 225 case FLOAT64: 226 return v.AsFloat64() 227 case FLOAT64SLICE: 228 return v.asFloat64Slice() 229 case STRING: 230 return v.stringly 231 case STRINGSLICE: 232 return v.asStringSlice() 233 } 234 return unknownValueType{} 235 } 236 237 // Emit returns a string representation of Value's data. 238 func (v Value) Emit() string { 239 switch v.Type() { 240 case BOOLSLICE: 241 return fmt.Sprint(v.asBoolSlice()) 242 case BOOL: 243 return strconv.FormatBool(v.AsBool()) 244 case INT64SLICE: 245 return fmt.Sprint(v.asInt64Slice()) 246 case INT64: 247 return strconv.FormatInt(v.AsInt64(), 10) 248 case FLOAT64SLICE: 249 return fmt.Sprint(v.asFloat64Slice()) 250 case FLOAT64: 251 return fmt.Sprint(v.AsFloat64()) 252 case STRINGSLICE: 253 return fmt.Sprint(v.asStringSlice()) 254 case STRING: 255 return v.stringly 256 default: 257 return "unknown" 258 } 259 } 260 261 // MarshalJSON returns the JSON encoding of the Value. 262 func (v Value) MarshalJSON() ([]byte, error) { 263 var jsonVal struct { 264 Type string 265 Value interface{} 266 } 267 jsonVal.Type = v.Type().String() 268 jsonVal.Value = v.AsInterface() 269 return json.Marshal(jsonVal) 270 }