123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
- //
- // This Source Code Form is subject to the terms of the MIT License.
- // If a copy of the MIT was not distributed with this file,
- // You can obtain one at https://github.com/gogf/gf.
- package gjson
- import (
- "fmt"
- "github.com/gogf/gf/v2/container/gvar"
- "github.com/gogf/gf/v2/errors/gcode"
- "github.com/gogf/gf/v2/errors/gerror"
- "github.com/gogf/gf/v2/util/gutil"
- )
- // Interface returns the json value.
- func (j *Json) Interface() interface{} {
- if j == nil {
- return nil
- }
- j.mu.RLock()
- defer j.mu.RUnlock()
- if j.p == nil {
- return nil
- }
- return *(j.p)
- }
- // Var returns the json value as *gvar.Var.
- func (j *Json) Var() *gvar.Var {
- return gvar.New(j.Interface())
- }
- // IsNil checks whether the value pointed by `j` is nil.
- func (j *Json) IsNil() bool {
- if j == nil {
- return true
- }
- j.mu.RLock()
- defer j.mu.RUnlock()
- return j.p == nil || *(j.p) == nil
- }
- // Get retrieves and returns value by specified `pattern`.
- // It returns all values of current Json object if `pattern` is given ".".
- // It returns nil if no value found by `pattern`.
- //
- // We can also access slice item by its index number in `pattern` like:
- // "list.10", "array.0.name", "array.0.1.id".
- //
- // It returns a default value specified by `def` if value for `pattern` is not found.
- func (j *Json) Get(pattern string, def ...interface{}) *gvar.Var {
- if j == nil {
- return nil
- }
- j.mu.RLock()
- defer j.mu.RUnlock()
- // It returns nil if pattern is empty.
- if pattern == "" {
- return nil
- }
- result := j.getPointerByPattern(pattern)
- if result != nil {
- return gvar.New(*result)
- }
- if len(def) > 0 {
- return gvar.New(def[0])
- }
- return nil
- }
- // GetJson gets the value by specified `pattern`,
- // and converts it to an un-concurrent-safe Json object.
- func (j *Json) GetJson(pattern string, def ...interface{}) *Json {
- return New(j.Get(pattern, def...).Val())
- }
- // GetJsons gets the value by specified `pattern`,
- // and converts it to a slice of un-concurrent-safe Json object.
- func (j *Json) GetJsons(pattern string, def ...interface{}) []*Json {
- array := j.Get(pattern, def...).Array()
- if len(array) > 0 {
- jsonSlice := make([]*Json, len(array))
- for i := 0; i < len(array); i++ {
- jsonSlice[i] = New(array[i])
- }
- return jsonSlice
- }
- return nil
- }
- // GetJsonMap gets the value by specified `pattern`,
- // and converts it to a map of un-concurrent-safe Json object.
- func (j *Json) GetJsonMap(pattern string, def ...interface{}) map[string]*Json {
- m := j.Get(pattern, def...).Map()
- if len(m) > 0 {
- jsonMap := make(map[string]*Json, len(m))
- for k, v := range m {
- jsonMap[k] = New(v)
- }
- return jsonMap
- }
- return nil
- }
- // Set sets value with specified `pattern`.
- // It supports hierarchical data access by char separator, which is '.' in default.
- func (j *Json) Set(pattern string, value interface{}) error {
- return j.setValue(pattern, value, false)
- }
- // MustSet performs as Set, but it panics if any error occurs.
- func (j *Json) MustSet(pattern string, value interface{}) {
- if err := j.Set(pattern, value); err != nil {
- panic(err)
- }
- }
- // Remove deletes value with specified `pattern`.
- // It supports hierarchical data access by char separator, which is '.' in default.
- func (j *Json) Remove(pattern string) error {
- return j.setValue(pattern, nil, true)
- }
- // MustRemove performs as Remove, but it panics if any error occurs.
- func (j *Json) MustRemove(pattern string) {
- if err := j.Remove(pattern); err != nil {
- panic(err)
- }
- }
- // Contains checks whether the value by specified `pattern` exist.
- func (j *Json) Contains(pattern string) bool {
- return j.Get(pattern) != nil
- }
- // Len returns the length/size of the value by specified `pattern`.
- // The target value by `pattern` should be type of slice or map.
- // It returns -1 if the target value is not found, or its type is invalid.
- func (j *Json) Len(pattern string) int {
- p := j.getPointerByPattern(pattern)
- if p != nil {
- switch (*p).(type) {
- case map[string]interface{}:
- return len((*p).(map[string]interface{}))
- case []interface{}:
- return len((*p).([]interface{}))
- default:
- return -1
- }
- }
- return -1
- }
- // Append appends value to the value by specified `pattern`.
- // The target value by `pattern` should be type of slice.
- func (j *Json) Append(pattern string, value interface{}) error {
- p := j.getPointerByPattern(pattern)
- if p == nil || *p == nil {
- if pattern == "." {
- return j.Set("0", value)
- }
- return j.Set(fmt.Sprintf("%s.0", pattern), value)
- }
- switch (*p).(type) {
- case []interface{}:
- if pattern == "." {
- return j.Set(fmt.Sprintf("%d", len((*p).([]interface{}))), value)
- }
- return j.Set(fmt.Sprintf("%s.%d", pattern, len((*p).([]interface{}))), value)
- }
- return gerror.NewCodef(gcode.CodeInvalidParameter, "invalid variable type of %s", pattern)
- }
- // MustAppend performs as Append, but it panics if any error occurs.
- func (j *Json) MustAppend(pattern string, value interface{}) {
- if err := j.Append(pattern, value); err != nil {
- panic(err)
- }
- }
- // Map converts current Json object to map[string]interface{}.
- // It returns nil if fails.
- func (j *Json) Map() map[string]interface{} {
- return j.Var().Map()
- }
- // Array converts current Json object to []interface{}.
- // It returns nil if fails.
- func (j *Json) Array() []interface{} {
- return j.Var().Array()
- }
- // Scan automatically calls Struct or Structs function according to the type of parameter
- // `pointer` to implement the converting.
- func (j *Json) Scan(pointer interface{}, mapping ...map[string]string) error {
- return j.Var().Scan(pointer, mapping...)
- }
- // Dump prints current Json object with more manually readable.
- func (j *Json) Dump() {
- if j == nil {
- return
- }
- j.mu.RLock()
- defer j.mu.RUnlock()
- gutil.Dump(*j.p)
- }
|