value.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // Copyright 2018 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package json implements the JSON format.
  5. // This package has no semantic understanding for protocol buffers and is only
  6. // a parser and composer for the format.
  7. //
  8. // This follows RFC 7159, with some notable implementation specifics:
  9. // * numbers that are out of range result in a decoding error
  10. // * duplicate keys in objects are not rejected
  11. //
  12. // Reasons why the standard encoding/json package is not suitable:
  13. // * information about duplicate keys is lost
  14. // * invalid UTF-8 is silently coerced into utf8.RuneError
  15. package json
  16. import (
  17. "fmt"
  18. "strings"
  19. )
  20. // Type represents a type expressible in the JSON format.
  21. type Type uint8
  22. const (
  23. _ Type = iota
  24. // Null is the null literal (i.e., "null").
  25. Null
  26. // Bool is a boolean (i.e., "true" or "false").
  27. Bool
  28. // Number is a floating-point number (e.g., "1.234" or "1e100").
  29. Number
  30. // String is an escaped string (e.g., `"the quick brown fox"`).
  31. String
  32. // Array is an ordered list of values (e.g., `[0, "one", true]`).
  33. Array
  34. // Object is an ordered map of values (e.g., `{"key": null}`).
  35. Object
  36. )
  37. func (t Type) String() string {
  38. switch t {
  39. case Null:
  40. return "null"
  41. case Bool:
  42. return "bool"
  43. case Number:
  44. return "number"
  45. case String:
  46. return "string"
  47. case Array:
  48. return "array"
  49. case Object:
  50. return "object"
  51. default:
  52. return "<invalid>"
  53. }
  54. }
  55. // Value contains a value of a given Type.
  56. type Value struct {
  57. typ Type
  58. raw []byte // raw bytes of the serialized data
  59. str string // only for String
  60. num float64 // only for Bool or Number
  61. arr []Value // only for Array
  62. obj [][2]Value // only for Object
  63. }
  64. // ValueOf returns a Value for a given Go value:
  65. // nil => Null
  66. // bool => Bool
  67. // int32, int64 => Number
  68. // uint32, uint64 => Number
  69. // float32, float64 => Number
  70. // string, []byte => String
  71. // []Value => Array
  72. // [][2]Value => Object
  73. //
  74. // ValueOf panics if the Go type is not one of the above.
  75. func ValueOf(v interface{}) Value {
  76. switch v := v.(type) {
  77. case nil:
  78. return Value{typ: Null}
  79. case bool:
  80. if v {
  81. return Value{typ: Bool, num: 1}
  82. } else {
  83. return Value{typ: Bool, num: 0}
  84. }
  85. case int32:
  86. return Value{typ: Number, num: float64(v)}
  87. case int64:
  88. return Value{typ: Number, num: float64(v)} // possible loss of precision
  89. case uint32:
  90. return Value{typ: Number, num: float64(v)}
  91. case uint64:
  92. return Value{typ: Number, num: float64(v)} // possible loss of precision
  93. case float32:
  94. return Value{typ: Number, num: float64(v)}
  95. case float64:
  96. return Value{typ: Number, num: float64(v)}
  97. case string:
  98. return Value{typ: String, str: string(v)}
  99. case []byte:
  100. return Value{typ: String, str: string(v)}
  101. case []Value:
  102. return Value{typ: Array, arr: v}
  103. case [][2]Value:
  104. return Value{typ: Object, obj: v}
  105. default:
  106. panic(fmt.Sprintf("invalid type %T", v))
  107. }
  108. }
  109. func rawValueOf(v interface{}, raw []byte) Value {
  110. v2 := ValueOf(v)
  111. v2.raw = raw
  112. return v2
  113. }
  114. // Type is the type of the value.
  115. func (v Value) Type() Type {
  116. return v.typ
  117. }
  118. // Bool returns v as a bool and panics if it is not a Bool.
  119. func (v Value) Bool() bool {
  120. if v.typ != Bool {
  121. panic("value is not a boolean")
  122. }
  123. return v.num != 0
  124. }
  125. // Number returns v as a float64 and panics if it is not a Number.
  126. func (v Value) Number() float64 {
  127. if v.typ != Number {
  128. panic("value is not a number")
  129. }
  130. return v.num
  131. }
  132. // String returns v as a string if the Type is String.
  133. // Otherwise, this returns a formatted string of v for debugging purposes.
  134. //
  135. // Since JSON strings must be UTF-8, the marshaler and unmarshaler will verify
  136. // for UTF-8 correctness.
  137. func (v Value) String() string {
  138. if v.typ != String {
  139. return v.stringValue()
  140. }
  141. return v.str
  142. }
  143. func (v Value) stringValue() string {
  144. switch v.typ {
  145. case Null, Bool, Number:
  146. return string(v.Raw())
  147. case Array:
  148. var ss []string
  149. for _, v := range v.Array() {
  150. ss = append(ss, v.String())
  151. }
  152. return "[" + strings.Join(ss, ",") + "]"
  153. case Object:
  154. var ss []string
  155. for _, v := range v.Object() {
  156. ss = append(ss, v[0].String()+":"+v[1].String())
  157. }
  158. return "{" + strings.Join(ss, ",") + "}"
  159. default:
  160. return "<invalid>"
  161. }
  162. }
  163. // Array returns the elements of v and panics if the Type is not Array.
  164. // Mutations on the return value may not be observable from the Raw method.
  165. func (v Value) Array() []Value {
  166. if v.typ != Array {
  167. panic("value is not an array")
  168. }
  169. return v.arr
  170. }
  171. // Object returns the items of v and panics if the Type is not Object.
  172. // The [2]Value represents a key (of type String) and value pair.
  173. //
  174. // Mutations on the return value may not be observable from the Raw method.
  175. func (v Value) Object() [][2]Value {
  176. if v.typ != Object {
  177. panic("value is not an object")
  178. }
  179. return v.obj
  180. }
  181. // Raw returns the raw representation of the value.
  182. // The returned value may alias the input given to Unmarshal.
  183. func (v Value) Raw() []byte {
  184. if len(v.raw) > 0 {
  185. return v.raw
  186. }
  187. p := encoder{}
  188. if err := p.marshalValue(v); !p.nerr.Merge(err) {
  189. return []byte("<invalid>")
  190. }
  191. return p.out
  192. }