Skip to content

Commit

Permalink
StringToDataType now can return an error when parsing a data type. No…
Browse files Browse the repository at this point in the history
…w all functions have a signature (can be void => void)
  • Loading branch information
redjack96 committed Aug 19, 2024
1 parent 20466d9 commit 2444265
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 27 deletions.
22 changes: 16 additions & 6 deletions internal/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/labstack/gommon/log"
"io"
"net/http"
"os"
Expand Down Expand Up @@ -255,10 +256,10 @@ func buildSignature() (*function.Signature, error) {
if len(tokens) < 2 {
return nil, fmt.Errorf("invalid input specification: %s", str)
}
if tokens[1] != "Int" && tokens[1] != "Text" && tokens[1] != "Float" && tokens[1] != "Bool" {
return nil, fmt.Errorf("invalid input specification: valid types are Int, Text, Float or Bool")
dataType, err := function.StringToDataType(tokens[1])
if err != nil {
return nil, fmt.Errorf("invalid signature input specification '%s': valid types are Int, Text, Float, Bool, Array[Int], Array[Text], Array[Float] or Array[Bool]\n", tokens[1])
}
dataType := function.StringToDataType(tokens[1])
sb = sb.AddInput(tokens[0], dataType)
}
}
Expand All @@ -268,7 +269,10 @@ func buildSignature() (*function.Signature, error) {
if len(tokens) < 2 {
return nil, fmt.Errorf("invalid output specification: %s", str)
}
dataType := function.StringToDataType(tokens[1])
dataType, err := function.StringToDataType(tokens[1])
if err != nil {
return nil, fmt.Errorf("invalid signature input specification '%s'. Available types are Int, Text, Float, Bool, ArrayInt, ArrayText, ArrayFloat, ArrayBool, ArrayArrayInt, ArrayArrayFloat\n", tokens[1])
}
sb = sb.AddOutput(tokens[0], dataType)
}
}
Expand Down Expand Up @@ -298,16 +302,22 @@ func create(cmd *cobra.Command, args []string) {
encoded = ""
}

// Signature: we only configure one if at least one input or output has been specified
// When signature is specified we build it from the input. Otherwise we defined an EMPTY signature (accepts and returns nothing)
var sig *function.Signature = nil
if (inputs != nil && len(inputs) > 0) || (outputs != nil && len(outputs) > 0) {
s, err := buildSignature()
if err != nil {
cmd.Help()
errHelp := cmd.Help()
if errHelp != nil {
log.Errorf("failed to call cmd.Help: %v\n", errHelp)
return
}
os.Exit(4)
}
sig = s
fmt.Printf("Parsed signature: %v\n", s)
} else {
sig = function.NewSignature().Build()
}

request := function.Function{Name: funcName, Handler: handler,
Expand Down
55 changes: 34 additions & 21 deletions internal/function/signature.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,32 @@ func (i InputDef) CheckInput(inputMap map[string]interface{}) error {
return fmt.Errorf("no input parameter with name '%s' and type '%s' exists", i.Name, i.Type)
}

t := StringToDataType(i.Type)
t, err := StringToDataType(i.Type)
if err != nil {
return err
}
if t == nil {
return fmt.Errorf("data type is too complex. Available types are Int, Text, Float, Bool, ArrayInt, ArrayText, ArrayFloat, ArrayBool, ArrayArrayInt, ArrayArrayFloat")
}

return StringToDataType(i.Type).TypeCheck(val)
dType, err := StringToDataType(i.Type)
if err != nil {
return fmt.Errorf("data type")
}
return dType.TypeCheck(val)
}

func (i InputDef) FindEntryThatTypeChecks(outputMap map[string]interface{}) (string, bool) {
for k, v := range outputMap {

t := StringToDataType(i.Type)
t, err := StringToDataType(i.Type)
if err != nil {
return "", false
}
if t == nil {
return "", false
}

err := t.TypeCheck(v)
err = t.TypeCheck(v)
if err == nil {
return k, true
}
Expand All @@ -69,17 +78,20 @@ func (o OutputDef) CheckOutput(inputMap map[string]interface{}) error {
if !exists {
return fmt.Errorf("no output parameter with name '%s' and type '%s' exists", o.Name, reflect.TypeOf(o.Type).Name())
}
t := StringToDataType(o.Type)
t, err := StringToDataType(o.Type)
if err != nil {
return err
}
if t != nil {
return t.TypeCheck(val)
}
return nil
}

func (o OutputDef) TryParse(result string) (interface{}, error) {
t := StringToDataType(o.Type)
if t == nil {
return nil, fmt.Errorf("type %s is not a compatible type", datatypeToString(t))
t, err := StringToDataType(o.Type)
if err != nil {
return nil, fmt.Errorf("type %s is not a compatible type", o.Type)
}
switch t.(type) {
case Int:
Expand Down Expand Up @@ -215,30 +227,31 @@ func (s *Signature) GetOutputs() []*OutputDef {
return s.Outputs
}

func StringToDataType(t string) DataTypeEnum {
// StringToDataType parses a dataType from a string. When it fails returns an error.
func StringToDataType(t string) (DataTypeEnum, error) {
switch t {
case INT:
return Int{}
return Int{}, nil
case FLOAT:
return Float{}
return Float{}, nil
case BOOL:
return Bool{}
return Bool{}, nil
case TEXT:
return Text{}
return Text{}, nil
case ARRAY_INT:
return Array[Int]{DataType: Int{}}
return Array[Int]{DataType: Int{}}, nil
case ARRAY_FLOAT:
return Array[Float]{DataType: Float{}}
return Array[Float]{DataType: Float{}}, nil
case ARRAY_BOOL:
return Array[Bool]{DataType: Bool{}}
return Array[Bool]{DataType: Bool{}}, nil
case ARRAY_TEXT:
return Array[Text]{DataType: Text{}}
return Array[Text]{DataType: Text{}}, nil
case ARRAY_ARRAY_INT:
return Array[Array[Int]]{DataType: Array[Int]{DataType: Int{}}}
return Array[Array[Int]]{DataType: Array[Int]{DataType: Int{}}}, nil
case ARRAY_ARRAY_FLOAT:
return Array[Array[Float]]{DataType: Array[Float]{DataType: Float{}}}
return Array[Array[Float]]{DataType: Array[Float]{DataType: Float{}}}, nil
default:
return nil
return nil, fmt.Errorf("invalid datatype: %s", t)
}
}

Expand Down

0 comments on commit 2444265

Please sign in to comment.