diff --git a/internal/processor/json-decode.go b/internal/processor/json-decode.go index 406acf1..11a805f 100644 --- a/internal/processor/json-decode.go +++ b/internal/processor/json-decode.go @@ -13,15 +13,20 @@ type JsonDecode struct { } func (jd *JsonDecode) Process(ctx context.Context, payload any) (any, error) { - payloadString, ok := GetAnyAs[string](payload) + + payloadBytes, ok := GetAnyAsByteSlice(payload) if !ok { - return nil, errors.New("json.decode processor only accepts a string") + payloadString, ok := GetAnyAs[string](payload) + if !ok { + return nil, errors.New("json.decode can only process a string or []byte") + } + payloadBytes = []byte(payloadString) } payloadJson := make(map[string]any) - err := json.Unmarshal([]byte(payloadString), &payloadJson) + err := json.Unmarshal(payloadBytes, &payloadJson) if err != nil { return nil, err } diff --git a/internal/processor/processor.go b/internal/processor/processor.go index be016a7..b0b605e 100644 --- a/internal/processor/processor.go +++ b/internal/processor/processor.go @@ -3,6 +3,8 @@ package processor import ( "context" "fmt" + "math" + "reflect" "sync" "github.com/jwetzell/showbridge-go/internal/common" @@ -47,6 +49,52 @@ func GetAnyAs[T any](p any) (T, bool) { return typed, ok } +func GetAnyAsByteSlice(p any) ([]byte, bool) { + v := reflect.ValueOf(p) + if v.Kind() != reflect.Slice { + return nil, false + } + + result := make([]byte, v.Len()) + for i := 0; i < v.Len(); i++ { + elem := v.Index(i).Interface() + byteValue, ok := elem.(byte) + if ok { + result[i] = byteValue + continue + } + uintValue, ok := elem.(uint) + if ok { + if uintValue > 255 { + return nil, false + } + result[i] = byte(uintValue) + continue + } + intValue, ok := elem.(int) + if ok { + if intValue < 0 || intValue > 255 { + return nil, false + } + result[i] = byte(intValue) + continue + } + floatValue, ok := elem.(float64) + if ok { + if floatValue != math.Floor(floatValue) { + return nil, false + } + if floatValue < 0 || floatValue > 255 { + return nil, false + } + result[i] = byte(floatValue) + continue + } + return nil, false + } + return result, true +} + type TemplateData struct { Payload any Modules any diff --git a/internal/processor/test/json-decode_test.go b/internal/processor/test/json-decode_test.go index 6a5f1f5..602b3e5 100644 --- a/internal/processor/test/json-decode_test.go +++ b/internal/processor/test/json-decode_test.go @@ -99,9 +99,9 @@ func TestBadJsonDecode(t *testing.T) { errorString string }{ { - name: "non-string input", - payload: []byte("hello"), - errorString: "json.decode processor only accepts a string", + name: "non-string or byte input", + payload: 123, + errorString: "json.decode can only process a string or []byte", }, { name: "invalid json",