Skip to content

Commit

Permalink
Merge pull request #2 from jaksonlin/develop
Browse files Browse the repository at this point in the history
add search by tag
  • Loading branch information
jaksonlin authored Oct 3, 2023
2 parents 0f10698 + 07bdabe commit ea9b9ad
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 6 deletions.
5 changes: 5 additions & 0 deletions interpreter/err.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const (
FieldTypeNotMatchAST = "field type %s is not of ast collection node type"
KVKindNotMatch = "expect %s as key but value is not :%#v"
FieldNotValid = "field not valid %s"
FieldNotFound = "field with tag %s not found"
)

var (
Expand Down Expand Up @@ -84,3 +85,7 @@ func NewErrorInternalMapKeyValueKindNotMatch(kind string, value interface{}) err
func NewErrorFieldNotValid(field string) error {
return fmt.Errorf(FieldNotValid, field)
}

func NewErrorFieldNotFound(field string) error {
return fmt.Errorf(FieldNotFound, field)
}
6 changes: 3 additions & 3 deletions interpreter/unmarshallResolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ func (resolver *unmarshallResolver) resolveSliceDependency(dependentResolver *un
return nil
}
func (resolver *unmarshallResolver) resolveStructDependency(dependentResolver *unmarshallResolver) error {
field := resolver.ptrToActualValue.Elem().FieldByName(dependentResolver.objectKey)
if !field.IsValid() || !field.CanSet() {
return NewErrFieldCannotSetOrNotfound(dependentResolver.objectKey)
field, err := resolver.getFieldByTag(resolver.ptrToActualValue.Elem(), dependentResolver.objectKey)
if err != nil {
return err
}

dependentValue := dependentResolver.restoreValue()
Expand Down
26 changes: 23 additions & 3 deletions interpreter/unmarshaller.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,26 @@ func (resolver *unmarshallResolver) processKVKeyNode(node ast.JsonStringValueNod
return key, nil
}

func (resolver *unmarshallResolver) getFieldByTag(obj reflect.Value, objKey string) (reflect.Value, error) {

for i := 0; i < obj.NumField(); i++ {
field := obj.Type().Field(i)
if fieldTag := field.Tag.Get("json"); fieldTag == objKey {
fieldInfo := obj.Field(i)
if !fieldInfo.IsValid() || !fieldInfo.CanSet() {
return reflect.Value{}, NewErrorFieldNotValid(objKey)
}
return fieldInfo, nil
}
}
// fall back to field by name
fieldInfo := obj.FieldByName(objKey)
if !fieldInfo.IsValid() || !fieldInfo.CanSet() {
return reflect.Value{}, NewErrorFieldNotValid(objKey)
}
return fieldInfo, nil
}

// create resolver to resolving the things in kv's value
func (resolver *unmarshallResolver) processKVValueNode(key string, valueNode ast.JsonNode) (*unmarshallResolver, error) {
// create child resolver by data type
Expand All @@ -34,9 +54,9 @@ func (resolver *unmarshallResolver) processKVValueNode(key string, valueNode ast

} else if childElementType.Kind() == reflect.Struct {

fieldInfo := resolver.ptrToActualValue.Elem().FieldByName(key) // struct field
if !fieldInfo.IsValid() || !fieldInfo.CanSet() {
return nil, NewErrorFieldNotValid(key)
fieldInfo, err := resolver.getFieldByTag(resolver.ptrToActualValue.Elem(), key) // struct field
if err != nil {
return nil, err
}
childElementType = fieldInfo.Type()

Expand Down
39 changes: 39 additions & 0 deletions interpreter/unmarshaller_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package interpreter_test

import (
"bytes"
"encoding/base64"
"encoding/json"
"fmt"
Expand Down Expand Up @@ -3147,3 +3148,41 @@ func TestVariable(t *testing.T) {
t.FailNow()
}
}

func TestFieldByTag(t *testing.T) {
type mydata struct {
Name1 string `json:"name"`
Name2 int `json:"age"`
Address string
}

test1 := mydata{"Ann", 198, "CA Redwood shore"}
data, _ := json.Marshal(test1)

var checker mydata
_ = json.Unmarshal(data, &checker)

sm := tokenizer.NewTokenizerStateMachine()
err := sm.ProcessData(bytes.NewReader(data))
if err != nil {
t.Log(err)
t.FailNow()
}
node := sm.GetASTConstructor().GetAST()
var myReceiver mydata
err = interpreter.UnmarshallAST(node, nil, &myReceiver)
if err != nil {
t.Log(err)
t.FailNow()
}
if myReceiver.Name1 != "Ann" {
t.FailNow()
}
if myReceiver.Name2 != 198 {
t.FailNow()
}
if myReceiver.Address != "CA Redwood shore" {
t.FailNow()
}

}

0 comments on commit ea9b9ad

Please sign in to comment.