Skip to content
Snippets Groups Projects
Verified Commit fef87b22 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

feat: implementation of basic features

parent d3fc2bc4
No related branches found
No related tags found
No related merge requests found
......@@ -9,7 +9,7 @@ func BenchmarkTransformer(b *testing.B) {
for i := 0; i < b.N; i++ {
tt := NewTransformer(m)
tt := NewTransformer(&m)
tt.Transform("static:AtEst | strtolower | strtoupper | prefix:b | md5")
}
......
......@@ -4,4 +4,6 @@ go 1.19
require github.com/volker-schukai/tokenizer v1.0.0
require gitlab.schukai.com/oss/libraries/go/utilities/pathfinder v0.4.0
replace github.com/volker-schukai/tokenizer => /home/volker.schukai/projekte/github/tokenizer
......@@ -10,6 +10,7 @@ const (
PipeCmdStatic
PipeCmdIndex
PipeCmdPath
PipeCmdToUpper
PipeCmdToLower
PipeCmdEmpty
......@@ -68,6 +69,7 @@ func initTokenizer() *tokenizer.Tokenizer {
parser.DefineTokens(PipeCmdStatic, []string{"static"})
parser.DefineTokens(PipeCmdIndex, []string{"index", "dataset"})
parser.DefineTokens(PipeCmdPath, []string{"path"})
parser.DefineTokens(PipeReflectionIsNil, []string{"isnull", "isnil"})
parser.DefineTokens(PipeCmdNop, []string{"nop"})
......
......@@ -10,6 +10,7 @@ import (
"errors"
"fmt"
"github.com/volker-schukai/tokenizer"
"gitlab.schukai.com/oss/libraries/go/utilities/pathfinder"
"html"
"math"
"net/url"
......@@ -20,16 +21,17 @@ import (
)
type Transformer struct {
dataset map[any]any
dataset *map[any]any
errors []error
parser *tokenizer.Tokenizer
}
type Number interface {
int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64
}
//
//type Number interface {
// int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64
//}
func NewTransformer(dataset map[any]any) *Transformer {
func NewTransformer(dataset *map[any]any) *Transformer {
parser := initTokenizer()
return &Transformer{
......@@ -53,6 +55,10 @@ func (t *Transformer) Transform(pipe string) (interface{}, error) {
return t.tokenize(pipe)
}
func (t *Transformer) Dataset() *map[any]any {
return t.dataset
}
func (t *Transformer) tokenize(pipe string) (any, error) {
// create tokens stream
......@@ -65,6 +71,9 @@ func (t *Transformer) tokenize(pipe string) (any, error) {
// iterate over each token
for stream.IsValid() {
token := stream.CurrentToken()
if token == nil {
break
}
stream.GoNext()
if token.Is(PipeSymbol) {
......@@ -85,8 +94,13 @@ func (t *Transformer) tokenize(pipe string) (any, error) {
}
var currentValue any
//datasetAvailable := true
currentValue = t.dataset
//if reflect.ValueOf(currentValue).IsNil() {
// datasetAvailable = false
//}
var err error
var ok bool
......@@ -107,30 +121,86 @@ func (t *Transformer) tokenize(pipe string) (any, error) {
continue
}
if tokens[0].Is(PipeCmdIndex) {
if tokens[0].Is(PipeCmdPath) {
if len(tokens) > 1 {
parts := []string{}
for _, token := range tokens[1:] {
parts = append(parts, token.ValueUnescapedString())
}
path := strings.Join(parts, "")
currentValue, err = pathfinder.GetValue[any](currentValue, path)
if err != nil {
return nil, err
}
} else {
return nil, errors.New("invalid path command")
}
continue
} else if tokens[0].Is(PipeCmdIndex) {
var index string
if index, err = handleIndexCommand(tokens); err != nil {
return nil, err
}
switch currentValue.(type) {
case *map[any]any:
if reflect.ValueOf(currentValue).IsNil() {
return nil, errors.New("index command on nil map")
}
currentValue, ok = (*currentValue.(*map[any]any))[index]
if !ok {
return nil, errors.New("index " + index + " not found")
}
case map[any]any:
currentValue, ok = currentValue.(map[any]any)[index]
if !ok {
t.errors = append(t.errors, errors.New("index not found: "+index))
}
case *map[string]any:
if reflect.ValueOf(currentValue).IsNil() {
return nil, errors.New("index command on nil map")
}
currentValue, ok = (*currentValue.(*map[string]any))[index]
if !ok {
t.errors = append(t.errors, errors.New("index not found: "+index))
}
case map[string]any:
currentValue, ok = currentValue.(map[string]any)[index]
if !ok {
t.errors = append(t.errors, errors.New("index not found: "+index))
}
case *[]string:
indexInt, err := strconv.Atoi(index)
if err != nil {
return nil, errors.New("index must be an integer")
}
currentValue = (*currentValue.(*[]string))[indexInt]
case []string:
indexInt, err := strconv.Atoi(index)
if err != nil {
return nil, err
}
currentValue = currentValue.([]string)[indexInt]
case *[]any:
indexInt, err := strconv.Atoi(index)
if err != nil {
return nil, err
}
currentValue = (*currentValue.(*[]any))[indexInt]
case []any:
indexInt, err := strconv.Atoi(index)
......@@ -141,8 +211,19 @@ func (t *Transformer) tokenize(pipe string) (any, error) {
if currentValue == nil {
t.errors = append(t.errors, errors.New("index not found: "+index))
}
default:
return nil, errors.New("invalid index command")
//var value generic[currentValue]
//
//genericValue := reflect.ValueOf(currentValue)
vxx, err := pathfinder.GetValue[any](currentValue, index)
fmt.Println(vxx, err)
//case struct{}:
// return nil, errors.New("index command on struct")
//
//default:
// return nil, errors.New("unsupported type " + reflect.TypeOf(currentValue).String())
}
continue
......@@ -177,16 +258,26 @@ func (t *Transformer) tokenize(pipe string) (any, error) {
continue
case *map[any]any:
v, ok := currentValue.(*map[any]any)
if !ok {
return nil, errors.New("invalid map")
}
if currentValue, err = handleMap(tokens, v); err != nil {
return nil, err
}
case map[any]any, map[string]any:
v, ok := currentValue.(map[any]any)
if !ok {
v = make(map[any]any)
m := make(map[any]any)
for k, vv := range currentValue.(map[string]any) {
v[k] = vv
m[k] = vv
}
v = m
}
if currentValue, err = handleMap(tokens, v); err != nil {
if currentValue, err = handleMap(tokens, &v); err != nil {
return nil, err
}
continue
......@@ -205,7 +296,7 @@ func (t *Transformer) tokenize(pipe string) (any, error) {
continue
default:
return nil, errors.New("invalid type")
return nil, errors.New("the type " + reflect.TypeOf(currentValue).String() + " is not supported")
}
return nil, errors.New("unknown command " + tokens[0].ValueUnescapedString())
......@@ -330,13 +421,13 @@ func handleFloat(tokens TokenList, currentValue float64) (any, error) {
return nil, errors.New(tokens[0].ValueString() + " is not a valid command for value of type float (" + strconv.FormatFloat(currentValue, 'f', -1, 64) + ")")
}
func handleMap(tokens TokenList, currentValue map[any]any) (any, error) {
func handleMap(tokens TokenList, currentValue *map[any]any) (any, error) {
if tokens[0].Is(PipeCmdToJSON) {
// convert to string map
stringMap := make(map[string]any)
for k, v := range currentValue {
for k, v := range *currentValue {
key, ok := k.(string)
if !ok {
return nil, errors.New("invalid key type for json conversion")
......
......@@ -5,7 +5,7 @@ import (
)
func TestNewTransformer(t *testing.T) {
tt := NewTransformer(map[any]any{})
tt := NewTransformer(&map[any]any{})
if tt == nil {
t.Error("Transformer is nil")
}
......@@ -638,7 +638,7 @@ func TestTransformValues(t *testing.T) {
t.Run(td.instruction, func(t *testing.T) {
tt := NewTransformer(td.data)
tt := NewTransformer(&td.data)
result, err := tt.Transform(td.instruction)
if td.hasError {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment