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  }