gjson_api.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
  2. //
  3. // This Source Code Form is subject to the terms of the MIT License.
  4. // If a copy of the MIT was not distributed with this file,
  5. // You can obtain one at https://github.com/gogf/gf.
  6. package gjson
  7. import (
  8. "fmt"
  9. "github.com/gogf/gf/v2/container/gvar"
  10. "github.com/gogf/gf/v2/errors/gcode"
  11. "github.com/gogf/gf/v2/errors/gerror"
  12. "github.com/gogf/gf/v2/util/gutil"
  13. )
  14. // Interface returns the json value.
  15. func (j *Json) Interface() interface{} {
  16. if j == nil {
  17. return nil
  18. }
  19. j.mu.RLock()
  20. defer j.mu.RUnlock()
  21. if j.p == nil {
  22. return nil
  23. }
  24. return *(j.p)
  25. }
  26. // Var returns the json value as *gvar.Var.
  27. func (j *Json) Var() *gvar.Var {
  28. return gvar.New(j.Interface())
  29. }
  30. // IsNil checks whether the value pointed by `j` is nil.
  31. func (j *Json) IsNil() bool {
  32. if j == nil {
  33. return true
  34. }
  35. j.mu.RLock()
  36. defer j.mu.RUnlock()
  37. return j.p == nil || *(j.p) == nil
  38. }
  39. // Get retrieves and returns value by specified `pattern`.
  40. // It returns all values of current Json object if `pattern` is given ".".
  41. // It returns nil if no value found by `pattern`.
  42. //
  43. // We can also access slice item by its index number in `pattern` like:
  44. // "list.10", "array.0.name", "array.0.1.id".
  45. //
  46. // It returns a default value specified by `def` if value for `pattern` is not found.
  47. func (j *Json) Get(pattern string, def ...interface{}) *gvar.Var {
  48. if j == nil {
  49. return nil
  50. }
  51. j.mu.RLock()
  52. defer j.mu.RUnlock()
  53. // It returns nil if pattern is empty.
  54. if pattern == "" {
  55. return nil
  56. }
  57. result := j.getPointerByPattern(pattern)
  58. if result != nil {
  59. return gvar.New(*result)
  60. }
  61. if len(def) > 0 {
  62. return gvar.New(def[0])
  63. }
  64. return nil
  65. }
  66. // GetJson gets the value by specified `pattern`,
  67. // and converts it to an un-concurrent-safe Json object.
  68. func (j *Json) GetJson(pattern string, def ...interface{}) *Json {
  69. return New(j.Get(pattern, def...).Val())
  70. }
  71. // GetJsons gets the value by specified `pattern`,
  72. // and converts it to a slice of un-concurrent-safe Json object.
  73. func (j *Json) GetJsons(pattern string, def ...interface{}) []*Json {
  74. array := j.Get(pattern, def...).Array()
  75. if len(array) > 0 {
  76. jsonSlice := make([]*Json, len(array))
  77. for i := 0; i < len(array); i++ {
  78. jsonSlice[i] = New(array[i])
  79. }
  80. return jsonSlice
  81. }
  82. return nil
  83. }
  84. // GetJsonMap gets the value by specified `pattern`,
  85. // and converts it to a map of un-concurrent-safe Json object.
  86. func (j *Json) GetJsonMap(pattern string, def ...interface{}) map[string]*Json {
  87. m := j.Get(pattern, def...).Map()
  88. if len(m) > 0 {
  89. jsonMap := make(map[string]*Json, len(m))
  90. for k, v := range m {
  91. jsonMap[k] = New(v)
  92. }
  93. return jsonMap
  94. }
  95. return nil
  96. }
  97. // Set sets value with specified `pattern`.
  98. // It supports hierarchical data access by char separator, which is '.' in default.
  99. func (j *Json) Set(pattern string, value interface{}) error {
  100. return j.setValue(pattern, value, false)
  101. }
  102. // MustSet performs as Set, but it panics if any error occurs.
  103. func (j *Json) MustSet(pattern string, value interface{}) {
  104. if err := j.Set(pattern, value); err != nil {
  105. panic(err)
  106. }
  107. }
  108. // Remove deletes value with specified `pattern`.
  109. // It supports hierarchical data access by char separator, which is '.' in default.
  110. func (j *Json) Remove(pattern string) error {
  111. return j.setValue(pattern, nil, true)
  112. }
  113. // MustRemove performs as Remove, but it panics if any error occurs.
  114. func (j *Json) MustRemove(pattern string) {
  115. if err := j.Remove(pattern); err != nil {
  116. panic(err)
  117. }
  118. }
  119. // Contains checks whether the value by specified `pattern` exist.
  120. func (j *Json) Contains(pattern string) bool {
  121. return j.Get(pattern) != nil
  122. }
  123. // Len returns the length/size of the value by specified `pattern`.
  124. // The target value by `pattern` should be type of slice or map.
  125. // It returns -1 if the target value is not found, or its type is invalid.
  126. func (j *Json) Len(pattern string) int {
  127. p := j.getPointerByPattern(pattern)
  128. if p != nil {
  129. switch (*p).(type) {
  130. case map[string]interface{}:
  131. return len((*p).(map[string]interface{}))
  132. case []interface{}:
  133. return len((*p).([]interface{}))
  134. default:
  135. return -1
  136. }
  137. }
  138. return -1
  139. }
  140. // Append appends value to the value by specified `pattern`.
  141. // The target value by `pattern` should be type of slice.
  142. func (j *Json) Append(pattern string, value interface{}) error {
  143. p := j.getPointerByPattern(pattern)
  144. if p == nil || *p == nil {
  145. if pattern == "." {
  146. return j.Set("0", value)
  147. }
  148. return j.Set(fmt.Sprintf("%s.0", pattern), value)
  149. }
  150. switch (*p).(type) {
  151. case []interface{}:
  152. if pattern == "." {
  153. return j.Set(fmt.Sprintf("%d", len((*p).([]interface{}))), value)
  154. }
  155. return j.Set(fmt.Sprintf("%s.%d", pattern, len((*p).([]interface{}))), value)
  156. }
  157. return gerror.NewCodef(gcode.CodeInvalidParameter, "invalid variable type of %s", pattern)
  158. }
  159. // MustAppend performs as Append, but it panics if any error occurs.
  160. func (j *Json) MustAppend(pattern string, value interface{}) {
  161. if err := j.Append(pattern, value); err != nil {
  162. panic(err)
  163. }
  164. }
  165. // Map converts current Json object to map[string]interface{}.
  166. // It returns nil if fails.
  167. func (j *Json) Map() map[string]interface{} {
  168. return j.Var().Map()
  169. }
  170. // Array converts current Json object to []interface{}.
  171. // It returns nil if fails.
  172. func (j *Json) Array() []interface{} {
  173. return j.Var().Array()
  174. }
  175. // Scan automatically calls Struct or Structs function according to the type of parameter
  176. // `pointer` to implement the converting.
  177. func (j *Json) Scan(pointer interface{}, mapping ...map[string]string) error {
  178. return j.Var().Scan(pointer, mapping...)
  179. }
  180. // Dump prints current Json object with more manually readable.
  181. func (j *Json) Dump() {
  182. if j == nil {
  183. return
  184. }
  185. j.mu.RLock()
  186. defer j.mu.RUnlock()
  187. gutil.Dump(*j.p)
  188. }