github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/tracer/exptel/key.go (about) 1 // Copyright 2019, 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 exptel 16 17 //go:generate stringer -type=ValueType 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "strconv" 23 "unsafe" 24 25 "go.opentelemetry.io/otel/attribute" 26 ) 27 28 // Key represents the key part in key-value pairs. It's a string. The 29 // allowed character set in the key depends on the use of the key. 30 type Key string 31 32 // KeyValue holds a key and value pair. 33 type KeyValue struct { 34 Key Key 35 Value Value 36 } 37 38 func NewKeyValuesFromOtel(kv []attribute.KeyValue) []KeyValue { 39 if kv == nil { 40 return nil 41 } 42 43 out := make([]KeyValue, len(kv)) 44 45 for i := range kv { 46 var v Value 47 48 // NOTE: array types are not supported and will result in an empty key-value after conversion 49 switch kv[i].Value.Type() { 50 case attribute.BOOL: 51 v = Bool(kv[i].Value.AsBool()) 52 case attribute.INT64: 53 v = Int64(kv[i].Value.AsInt64()) 54 case attribute.FLOAT64: 55 v = Float64(kv[i].Value.AsFloat64()) 56 case attribute.STRING: 57 v = String(kv[i].Value.AsString()) 58 } 59 60 out[i] = KeyValue{ 61 Key: Key(kv[i].Key), 62 Value: v, 63 } 64 } 65 return out 66 } 67 68 // ValueType describes the type of the data Value holds. 69 type ValueType int 70 71 // Value represents the value part in key-value pairs. 72 type Value struct { 73 vtype ValueType 74 numeric uint64 75 stringly string 76 // TODO Lazy value type? 77 } 78 79 const ( 80 INVALID ValueType = iota // No value. 81 BOOL // Boolean value, use AsBool() to get it. 82 INT32 // 32 bit signed integral value, use AsInt32() to get it. 83 INT64 // 64 bit signed integral value, use AsInt64() to get it. 84 UINT32 // 32 bit unsigned integral value, use AsUint32() to get it. 85 UINT64 // 64 bit unsigned integral value, use AsUint64() to get it. 86 FLOAT32 // 32 bit floating point value, use AsFloat32() to get it. 87 FLOAT64 // 64 bit floating point value, use AsFloat64() to get it. 88 STRING // String value, use AsString() to get it. 89 ) 90 91 // Bool creates a BOOL Value. 92 func Bool(v bool) Value { 93 return Value{ 94 vtype: BOOL, 95 numeric: boolToRaw(v), 96 } 97 } 98 99 // Int64 creates an INT64 Value. 100 func Int64(v int64) Value { 101 return Value{ 102 vtype: INT64, 103 numeric: int64ToRaw(v), 104 } 105 } 106 107 // Uint64 creates a UINT64 Value. 108 func Uint64(v uint64) Value { 109 return Value{ 110 vtype: UINT64, 111 numeric: uint64ToRaw(v), 112 } 113 } 114 115 // Float64 creates a FLOAT64 Value. 116 func Float64(v float64) Value { 117 return Value{ 118 vtype: FLOAT64, 119 numeric: float64ToRaw(v), 120 } 121 } 122 123 // Int32 creates an INT32 Value. 124 func Int32(v int32) Value { 125 return Value{ 126 vtype: INT32, 127 numeric: int32ToRaw(v), 128 } 129 } 130 131 // Uint32 creates a UINT32 Value. 132 func Uint32(v uint32) Value { 133 return Value{ 134 vtype: UINT32, 135 numeric: uint32ToRaw(v), 136 } 137 } 138 139 // Float32 creates a FLOAT32 Value. 140 func Float32(v float32) Value { 141 return Value{ 142 vtype: FLOAT32, 143 numeric: float32ToRaw(v), 144 } 145 } 146 147 // String creates a STRING Value. 148 func String(v string) Value { 149 return Value{ 150 vtype: STRING, 151 stringly: v, 152 } 153 } 154 155 // Int creates either an INT32 or an INT64 Value, depending on whether 156 // the int type is 32 or 64 bits wide. 157 func Int(v int) Value { 158 if unsafe.Sizeof(v) == 4 { 159 return Int32(int32(v)) 160 } 161 return Int64(int64(v)) 162 } 163 164 // Uint creates either a UINT32 or a UINT64 Value, depending on 165 // whether the uint type is 32 or 64 bits wide. 166 func Uint(v uint) Value { 167 if unsafe.Sizeof(v) == 4 { 168 return Uint32(uint32(v)) 169 } 170 return Uint64(uint64(v)) 171 } 172 173 // Bool creates a KeyValue instance with a BOOL Value. 174 func (k Key) Bool(v bool) KeyValue { 175 return KeyValue{ 176 Key: k, 177 Value: Bool(v), 178 } 179 } 180 181 // Int64 creates a KeyValue instance with an INT64 Value. 182 func (k Key) Int64(v int64) KeyValue { 183 return KeyValue{ 184 Key: k, 185 Value: Int64(v), 186 } 187 } 188 189 // Uint64 creates a KeyValue instance with a UINT64 Value. 190 func (k Key) Uint64(v uint64) KeyValue { 191 return KeyValue{ 192 Key: k, 193 Value: Uint64(v), 194 } 195 } 196 197 // Float64 creates a KeyValue instance with a FLOAT64 Value. 198 func (k Key) Float64(v float64) KeyValue { 199 return KeyValue{ 200 Key: k, 201 Value: Float64(v), 202 } 203 } 204 205 // Int32 creates a KeyValue instance with an INT32 Value. 206 func (k Key) Int32(v int32) KeyValue { 207 return KeyValue{ 208 Key: k, 209 Value: Int32(v), 210 } 211 } 212 213 // Uint32 creates a KeyValue instance with a UINT32 Value. 214 func (k Key) Uint32(v uint32) KeyValue { 215 return KeyValue{ 216 Key: k, 217 Value: Uint32(v), 218 } 219 } 220 221 // Float32 creates a KeyValue instance with a FLOAT32 Value. 222 func (k Key) Float32(v float32) KeyValue { 223 return KeyValue{ 224 Key: k, 225 Value: Float32(v), 226 } 227 } 228 229 // String creates a KeyValue instance with a STRING Value. 230 func (k Key) String(v string) KeyValue { 231 return KeyValue{ 232 Key: k, 233 Value: String(v), 234 } 235 } 236 237 // Int creates a KeyValue instance with either an INT32 or an INT64 238 // Value, depending on whether the int type is 32 or 64 bits wide. 239 func (k Key) Int(v int) KeyValue { 240 return KeyValue{ 241 Key: k, 242 Value: Int(v), 243 } 244 } 245 246 // Uint creates a KeyValue instance with either an UINT32 or an UINT64 247 // Value, depending on whether the uint type is 32 or 64 bits wide. 248 func (k Key) Uint(v uint) KeyValue { 249 return KeyValue{ 250 Key: k, 251 Value: Uint(v), 252 } 253 } 254 255 // Defined returns true for non-empty keys. 256 func (k Key) Defined() bool { 257 return len(k) != 0 258 } 259 260 // Type returns a type of the Value. 261 func (v *Value) Type() ValueType { 262 return v.vtype 263 } 264 265 // Bool returns the bool value. Make sure that the Value's type is 266 // BOOL. 267 func (v *Value) AsBool() bool { 268 return rawToBool(v.numeric) 269 } 270 271 // AsInt32 returns the int32 value. Make sure that the Value's type is 272 // INT32. 273 func (v *Value) AsInt32() int32 { 274 return rawToInt32(v.numeric) 275 } 276 277 // AsInt64 returns the int64 value. Make sure that the Value's type is 278 // INT64. 279 func (v *Value) AsInt64() int64 { 280 return rawToInt64(v.numeric) 281 } 282 283 // AsUint32 returns the uint32 value. Make sure that the Value's type 284 // is UINT32. 285 func (v *Value) AsUint32() uint32 { 286 return rawToUint32(v.numeric) 287 } 288 289 // AsUint64 returns the uint64 value. Make sure that the Value's type is 290 // UINT64. 291 func (v *Value) AsUint64() uint64 { 292 return rawToUint64(v.numeric) 293 } 294 295 // AsFloat32 returns the float32 value. Make sure that the Value's 296 // type is FLOAT32. 297 func (v *Value) AsFloat32() float32 { 298 return rawToFloat32(v.numeric) 299 } 300 301 // AsFloat64 returns the float64 value. Make sure that the Value's 302 // type is FLOAT64. 303 func (v *Value) AsFloat64() float64 { 304 return rawToFloat64(v.numeric) 305 } 306 307 // AsString returns the string value. Make sure that the Value's type 308 // is STRING. 309 func (v *Value) AsString() string { 310 return v.stringly 311 } 312 313 type unknownValueType struct{} 314 315 // AsInterface returns Value's data as interface{}. 316 func (v *Value) AsInterface() interface{} { 317 switch v.Type() { 318 case BOOL: 319 return v.AsBool() 320 case INT32: 321 return v.AsInt32() 322 case INT64: 323 return v.AsInt64() 324 case UINT32: 325 return v.AsUint32() 326 case UINT64: 327 return v.AsUint64() 328 case FLOAT32: 329 return v.AsFloat32() 330 case FLOAT64: 331 return v.AsFloat64() 332 case STRING: 333 return v.stringly 334 } 335 return unknownValueType{} 336 } 337 338 // Emit returns a string representation of Value's data. 339 func (v *Value) Emit() string { 340 switch v.Type() { 341 case BOOL: 342 return strconv.FormatBool(v.AsBool()) 343 case INT32: 344 return strconv.FormatInt(int64(v.AsInt32()), 10) 345 case INT64: 346 return strconv.FormatInt(v.AsInt64(), 10) 347 case UINT32: 348 return strconv.FormatUint(uint64(v.AsUint32()), 10) 349 case UINT64: 350 return strconv.FormatUint(v.AsUint64(), 10) 351 case FLOAT32: 352 return fmt.Sprint(v.AsFloat32()) 353 case FLOAT64: 354 return fmt.Sprint(v.AsFloat64()) 355 case STRING: 356 return v.stringly 357 default: 358 return "unknown" 359 } 360 } 361 362 // MarshalJSON returns the JSON encoding of the Value. 363 func (v *Value) MarshalJSON() ([]byte, error) { 364 var jsonVal struct { 365 Type string 366 Value interface{} 367 } 368 jsonVal.Type = v.Type().String() 369 jsonVal.Value = v.AsInterface() 370 return json.Marshal(jsonVal) 371 }