value.go 6.1 KB

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