github.com/3JoB/go-json@v0.10.4/path.go (about)

     1  package json
     2  
     3  import (
     4  	"github.com/3JoB/go-reflect"
     5  
     6  	"github.com/3JoB/go-json/internal/decoder"
     7  )
     8  
     9  // CreatePath creates JSON Path.
    10  //
    11  // JSON Path rule
    12  // $   : root object or element. The JSON Path format must start with this operator, which refers to the outermost level of the JSON-formatted string.
    13  // .   : child operator. You can identify child values using dot-notation.
    14  // ..  : recursive descent.
    15  // []  : subscript operator. If the JSON object is an array, you can use brackets to specify the array index.
    16  // [*] : all objects/elements for array.
    17  //
    18  // Reserved words must be properly escaped when included in Path.
    19  //
    20  // Escape Rule
    21  // single quote style escape: e.g.) `$['a.b'].c`
    22  // double quote style escape: e.g.) `$."a.b".c`
    23  func CreatePath(p string) (*Path, error) {
    24  	path, err := decoder.PathString(p).Build()
    25  	if err != nil {
    26  		return nil, err
    27  	}
    28  	return &Path{path: path}, nil
    29  }
    30  
    31  // Path represents JSON Path.
    32  type Path struct {
    33  	path *decoder.Path
    34  }
    35  
    36  // RootSelectorOnly whether only the root selector ($) is used.
    37  func (p *Path) RootSelectorOnly() bool {
    38  	return p.path.RootSelectorOnly
    39  }
    40  
    41  // UsedSingleQuotePathSelector whether single quote-based escaping was done when building the JSON Path.
    42  func (p *Path) UsedSingleQuotePathSelector() bool {
    43  	return p.path.SingleQuotePathSelector
    44  }
    45  
    46  // UsedSingleQuotePathSelector whether double quote-based escaping was done when building the JSON Path.
    47  func (p *Path) UsedDoubleQuotePathSelector() bool {
    48  	return p.path.DoubleQuotePathSelector
    49  }
    50  
    51  // Extract extracts a specific JSON string.
    52  func (p *Path) Extract(data []byte, optFuncs ...DecodeOptionFunc) ([][]byte, error) {
    53  	return extractFromPath(p, data, optFuncs...)
    54  }
    55  
    56  // PathString returns original JSON Path string.
    57  func (p *Path) PathString() string {
    58  	return p.path.String()
    59  }
    60  
    61  // Unmarshal extract and decode the value of the part corresponding to JSON Path from the input data.
    62  func (p *Path) Unmarshal(data []byte, v any, optFuncs ...DecodeOptionFunc) error {
    63  	contents, err := extractFromPath(p, data, optFuncs...)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	results := make([]any, 0, len(contents))
    68  	for _, content := range contents {
    69  		var result any
    70  		if err := Unmarshal(content, &result); err != nil {
    71  			return err
    72  		}
    73  		results = append(results, result)
    74  	}
    75  	if err := decoder.AssignValue(reflect.ValueOf(results), reflect.ValueOf(v)); err != nil {
    76  		return err
    77  	}
    78  	return nil
    79  }
    80  
    81  // Get extract and substitute the value of the part corresponding to JSON Path from the input value.
    82  func (p *Path) Get(src, dst any) error {
    83  	return p.path.Get(reflect.ValueOf(src), reflect.ValueOf(dst))
    84  }