...

Source file src/github.com/PaesslerAG/jsonpath/path.go

Documentation: github.com/PaesslerAG/jsonpath

     1  package jsonpath
     2  
     3  import "context"
     4  
     5  type path interface {
     6  	evaluate(c context.Context, parameter interface{}) (interface{}, error)
     7  	visitMatchs(c context.Context, r interface{}, visit pathMatcher)
     8  	withPlainSelector(plainSelector) path
     9  	withAmbiguousSelector(ambiguousSelector) path
    10  }
    11  
    12  type plainPath []plainSelector
    13  
    14  type ambiguousMatcher func(key, v interface{})
    15  
    16  func (p plainPath) evaluate(ctx context.Context, root interface{}) (interface{}, error) {
    17  	return p.evaluatePath(ctx, root, root)
    18  }
    19  
    20  func (p plainPath) evaluatePath(ctx context.Context, root, value interface{}) (interface{}, error) {
    21  	var err error
    22  	for _, sel := range p {
    23  		value, err = sel(ctx, root, value)
    24  		if err != nil {
    25  			return nil, err
    26  		}
    27  	}
    28  	return value, nil
    29  }
    30  
    31  func (p plainPath) matcher(ctx context.Context, r interface{}, match ambiguousMatcher) ambiguousMatcher {
    32  	if len(p) == 0 {
    33  		return match
    34  	}
    35  	return func(k, v interface{}) {
    36  		res, err := p.evaluatePath(ctx, r, v)
    37  		if err == nil {
    38  			match(k, res)
    39  		}
    40  	}
    41  }
    42  
    43  func (p plainPath) visitMatchs(ctx context.Context, r interface{}, visit pathMatcher) {
    44  	res, err := p.evaluatePath(ctx, r, r)
    45  	if err == nil {
    46  		visit(nil, res)
    47  	}
    48  }
    49  
    50  func (p plainPath) withPlainSelector(selector plainSelector) path {
    51  	return append(p, selector)
    52  }
    53  func (p plainPath) withAmbiguousSelector(selector ambiguousSelector) path {
    54  	return &ambiguousPath{
    55  		parent: p,
    56  		branch: selector,
    57  	}
    58  }
    59  
    60  type ambiguousPath struct {
    61  	parent path
    62  	branch ambiguousSelector
    63  	ending plainPath
    64  }
    65  
    66  func (p *ambiguousPath) evaluate(ctx context.Context, parameter interface{}) (interface{}, error) {
    67  	matchs := []interface{}{}
    68  	p.visitMatchs(ctx, parameter, func(keys []interface{}, match interface{}) {
    69  		matchs = append(matchs, match)
    70  	})
    71  	return matchs, nil
    72  }
    73  
    74  func (p *ambiguousPath) visitMatchs(ctx context.Context, r interface{}, visit pathMatcher) {
    75  	p.parent.visitMatchs(ctx, r, func(keys []interface{}, v interface{}) {
    76  		p.branch(ctx, r, v, p.ending.matcher(ctx, r, visit.matcher(keys)))
    77  	})
    78  }
    79  
    80  func (p *ambiguousPath) branchMatcher(ctx context.Context, r interface{}, m ambiguousMatcher) ambiguousMatcher {
    81  	return func(k, v interface{}) {
    82  		p.branch(ctx, r, v, m)
    83  	}
    84  }
    85  
    86  func (p *ambiguousPath) withPlainSelector(selector plainSelector) path {
    87  	p.ending = append(p.ending, selector)
    88  	return p
    89  }
    90  func (p *ambiguousPath) withAmbiguousSelector(selector ambiguousSelector) path {
    91  	return &ambiguousPath{
    92  		parent: p,
    93  		branch: selector,
    94  	}
    95  }
    96  
    97  type pathMatcher func(keys []interface{}, match interface{})
    98  
    99  func (m pathMatcher) matcher(keys []interface{}) ambiguousMatcher {
   100  	return func(key, match interface{}) {
   101  		m(append(keys, key), match)
   102  	}
   103  }
   104  

View as plain text