61 lines
1.2 KiB
Go
61 lines
1.2 KiB
Go
package jsonpointer
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func get(doc interface{}, tokens []string) (interface{}, error) {
|
|
if len(tokens) == 0 {
|
|
return doc, nil
|
|
}
|
|
|
|
currentToken := tokens[0]
|
|
|
|
if doc == nil {
|
|
return nil, errors.Wrapf(ErrNotFound, "pointer '%s' not found on document", tokensToString(tokens))
|
|
}
|
|
|
|
switch typedDoc := doc.(type) {
|
|
case map[string]interface{}:
|
|
value, exists := typedDoc[currentToken]
|
|
if !exists {
|
|
return nil, errors.Wrapf(ErrNotFound, "pointer '%s' not found on document", tokensToString(tokens))
|
|
}
|
|
|
|
value, err := get(value, tokens[1:])
|
|
if err != nil {
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
|
|
return value, nil
|
|
|
|
case []interface{}:
|
|
if currentToken == NonExistentMemberToken {
|
|
return nil, errors.WithStack(ErrOutOfBounds)
|
|
}
|
|
|
|
index, err := strconv.ParseUint(currentToken, 10, 64)
|
|
if err != nil {
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
|
|
if len(typedDoc) <= int(index) {
|
|
return nil, errors.WithStack(ErrOutOfBounds)
|
|
}
|
|
|
|
value := typedDoc[index]
|
|
|
|
value, err = get(value, tokens[1:])
|
|
if err != nil {
|
|
return nil, errors.WithStack(err)
|
|
}
|
|
|
|
return value, nil
|
|
|
|
default:
|
|
return nil, errors.Wrapf(ErrUnexpectedType, "unexpected type '%T'", typedDoc)
|
|
}
|
|
}
|