add convenience method to pull params from config

This commit is contained in:
Joel Wetzell
2026-03-01 14:57:19 -06:00
parent 183182e6cd
commit c298f63ffc
69 changed files with 591 additions and 1081 deletions

View File

@@ -1,14 +1,69 @@
package config
import (
"errors"
)
type Config struct {
Modules []ModuleConfig `json:"modules"`
Routes []RouteConfig `json:"routes"`
}
type Params map[string]any
var (
ErrParamNotFound = errors.New("not found")
ErrParamNotString = errors.New("not a string")
ErrParamNotNumber = errors.New("not a number")
)
func (p Params) GetString(key string) (string, error) {
value, ok := p[key]
if !ok {
return "", ErrParamNotFound
}
stringValue, ok := value.(string)
if !ok {
return "", ErrParamNotString
}
return stringValue, nil
}
func (p Params) GetInt(key string) (int, error) {
value, ok := p[key]
if !ok {
return 0, ErrParamNotFound
}
intValue, ok := value.(int)
if !ok {
floatValue, ok := value.(float64)
if !ok {
return 0, ErrParamNotNumber
}
intValue = int(floatValue)
}
return intValue, nil
}
func (p Params) GetBool(key string) (bool, error) {
value, ok := p[key]
if !ok {
return false, ErrParamNotFound
}
boolValue, ok := value.(bool)
if !ok {
return false, errors.New("not a bool")
}
return boolValue, nil
}
type ModuleConfig struct {
Id string `json:"id"`
Type string `json:"type"`
Params map[string]any `json:"params"`
Id string `json:"id"`
Type string `json:"type"`
Params Params `json:"params"`
}
type RouteConfig struct {
@@ -18,6 +73,6 @@ type RouteConfig struct {
}
type ProcessorConfig struct {
Type string `json:"type"`
Params map[string]any `json:"params"`
Type string `json:"type"`
Params Params `json:"params"`
}

View File

@@ -57,17 +57,10 @@ func init() {
Type: "http.server",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
port, ok := params["port"]
if !ok {
return nil, errors.New("http.server requires a port parameter")
portNum, err := params.GetInt("port")
if err != nil {
return nil, fmt.Errorf("http.server port error: %w", err)
}
portNum, ok := port.(float64)
if !ok {
return nil, errors.New("http.server port must be a number")
}
return &HTTPServer{Port: uint16(portNum), config: config, logger: CreateLogger(config)}, nil
},
})

View File

@@ -29,16 +29,9 @@ func init() {
Type: "midi.input",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
port, ok := params["port"]
if !ok {
return nil, errors.New("midi.input requires a port parameter")
}
portString, ok := port.(string)
if !ok {
return nil, errors.New("midi.input port must be a string")
portString, err := params.GetString("port")
if err != nil {
return nil, fmt.Errorf("midi.input port error: %w", err)
}
return &MIDIInput{config: config, Port: portString, logger: CreateLogger(config)}, nil

View File

@@ -30,16 +30,9 @@ func init() {
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
port, ok := params["port"]
if !ok {
return nil, errors.New("midi.output requires a port parameter")
}
portString, ok := port.(string)
if !ok {
return nil, errors.New("midi.output port must be a string")
portString, err := params.GetString("port")
if err != nil {
return nil, fmt.Errorf("midi.output port error: %w", err)
}
return &MIDIOutput{config: config, Port: portString, logger: CreateLogger(config)}, nil

View File

@@ -3,6 +3,7 @@ package module
import (
"context"
"errors"
"fmt"
"log/slog"
mqtt "github.com/eclipse/paho.mqtt.golang"
@@ -27,40 +28,22 @@ func init() {
Type: "mqtt.client",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
broker, ok := params["broker"]
brokerString, err := params.GetString("broker")
if !ok {
return nil, errors.New("mqtt.client requires a broker parameter")
if err != nil {
return nil, fmt.Errorf("mqtt.client broker error: %w", err)
}
brokerString, ok := broker.(string)
topicString, err := params.GetString("topic")
if !ok {
return nil, errors.New("mqtt.client broker must be a string")
if err != nil {
return nil, fmt.Errorf("mqtt.client topic error: %w", err)
}
topic, ok := params["topic"]
clientIdString, err := params.GetString("clientId")
if !ok {
return nil, errors.New("mqtt.client requires a topic parameter")
}
topicString, ok := topic.(string)
if !ok {
return nil, errors.New("mqtt.client topic must be a string")
}
clientId, ok := params["clientId"]
if !ok {
return nil, errors.New("mqtt.client requires a clientId parameter")
}
clientIdString, ok := clientId.(string)
if !ok {
return nil, errors.New("mqtt.client clientId must be a string")
if err != nil {
return nil, fmt.Errorf("mqtt.client clientId error: %w", err)
}
return &MQTTClient{config: config, Broker: brokerString, Topic: topicString, ClientID: clientIdString, logger: CreateLogger(config)}, nil

View File

@@ -27,28 +27,15 @@ func init() {
Type: "nats.client",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
url, ok := params["url"]
if !ok {
return nil, errors.New("nats.client requires a url parameter")
urlString, err := params.GetString("url")
if err != nil {
return nil, errors.New("nats.client url error: " + err.Error())
}
urlString, ok := url.(string)
subjectString, err := params.GetString("subject")
if !ok {
return nil, errors.New("nats.client url must be a string")
}
subject, ok := params["subject"]
if !ok {
return nil, errors.New("nats.client requires a subject parameter")
}
subjectString, ok := subject.(string)
if !ok {
return nil, errors.New("nats.client subject must be a string")
if err != nil {
return nil, errors.New("nats.client subject error: " + err.Error())
}
return &NATSClient{config: config, URL: urlString, Subject: subjectString, logger: CreateLogger(config)}, nil

View File

@@ -27,42 +27,31 @@ type NATSServer struct {
func init() {
RegisterModule(ModuleRegistration{
Type: "nats.server",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
portNum := 4222
port, ok := params["port"]
if ok {
specificportNum, ok := port.(int)
if !ok {
specificportNum, ok := port.(float64)
if !ok {
return nil, errors.New("nats.server port must be a number")
}
portNum = int(specificportNum)
New: func(moduleConfig config.ModuleConfig) (Module, error) {
params := moduleConfig.Params
portNum, err := params.GetInt("port")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
portNum = 4222
} else {
portNum = int(specificportNum)
return nil, fmt.Errorf("nats.server port error: %w", err)
}
}
ipString := "0.0.0.0"
ip, ok := params["ip"]
if ok {
specificIpString, ok := ip.(string)
if !ok {
return nil, errors.New("nats.server ip must be a string")
ipString, err := params.GetString("ip")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
ipString = "0.0.0.0"
} else {
return nil, fmt.Errorf("nats.server ip error: %w", err)
}
ipString = specificIpString
}
_, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ipString, uint16(portNum)))
_, err = net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ipString, uint16(portNum)))
if err != nil {
return nil, err
}
return &NATSServer{config: config, logger: CreateLogger(config), Ip: ipString, Port: portNum}, nil
return &NATSServer{config: moduleConfig, logger: CreateLogger(moduleConfig), Ip: ipString, Port: portNum}, nil
},
})
}

View File

@@ -32,48 +32,29 @@ func init() {
Type: "serial.client",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
port, ok := params["port"]
if !ok {
return nil, errors.New("serial.client requires a port parameter")
portString, err := params.GetString("port")
if err != nil {
return nil, fmt.Errorf("serial.client port error: %w", err)
}
portString, ok := port.(string)
if !ok {
return nil, errors.New("serial.client port must be a string")
}
framingMethod, ok := params["framing"]
if !ok {
return nil, errors.New("serial.client requires a framing parameter")
}
framingMethodString, ok := framingMethod.(string)
if !ok {
return nil, errors.New("serial.client framing method must be a string")
framingMethodString, err := params.GetString("framing")
if err != nil {
return nil, fmt.Errorf("serial.client framing error: %w", err)
}
framer := framer.GetFramer(framingMethodString)
if framer == nil {
return nil, fmt.Errorf("serial.client unknown framing method: %s", framingMethod)
return nil, fmt.Errorf("serial.client unknown framing method: %s", framingMethodString)
}
buadRate, ok := params["baudRate"]
if !ok {
return nil, errors.New("serial.client requires a baudRate parameter")
}
baudRateNum, ok := buadRate.(float64)
if !ok {
return nil, errors.New("serial.client baudRate must be a number")
baudRateInt, err := params.GetInt("baudRate")
if err != nil {
return nil, fmt.Errorf("serial.client baudRate error: %w", err)
}
mode := serial.Mode{
BaudRate: int(baudRateNum),
BaudRate: baudRateInt,
}
return &SerialClient{config: config, Port: portString, Framer: framer, Mode: &mode, logger: CreateLogger(config)}, nil

View File

@@ -46,60 +46,46 @@ type sipCallContextKey string
func init() {
RegisterModule(ModuleRegistration{
Type: "sip.call.server",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
portNum := 5060
New: func(moduleConfig config.ModuleConfig) (Module, error) {
params := moduleConfig.Params
portNum, err := params.GetInt("port")
if err != nil {
port, ok := params["port"]
if ok {
specificPortNum, ok := port.(float64)
if !ok {
return nil, errors.New("sip.call.server port must be a number")
if errors.Is(err, config.ErrParamNotFound) {
portNum = 5060
} else {
return nil, fmt.Errorf("sip.call.server port error: %w", err)
}
portNum = int(specificPortNum)
}
ipString := "0.0.0.0"
ip, ok := params["ip"]
if ok {
specificIpString, ok := ip.(string)
if !ok {
return nil, errors.New("sip.call.server ip must be a string")
ipString, err := params.GetString("ip")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
ipString = "0.0.0.0"
} else {
return nil, fmt.Errorf("sip.call.server ip error: %w", err)
}
ipString = specificIpString
}
transportString := "udp"
transport, ok := params["transport"]
if ok {
specificTransportString, ok := transport.(string)
if !ok {
return nil, errors.New("sip.call.server transport must be a string")
transportString, err := params.GetString("transport")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
transportString = "udp"
} else {
return nil, fmt.Errorf("sip.call.server transport error: %w", err)
}
transportString = specificTransportString
}
userAgentString := "showbridge"
userAgent, ok := params["userAgent"]
if ok {
specificUserAgentString, ok := userAgent.(string)
if !ok {
return nil, errors.New("sip.call.server userAgent must be a string")
userAgentString, err := params.GetString("userAgent")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
userAgentString = "showbridge"
} else {
return nil, fmt.Errorf("sip.call.server userAgent error: %w", err)
}
userAgentString = specificUserAgentString
}
return &SIPCallServer{config: config, IP: ipString, Port: int(portNum), Transport: transportString, UserAgent: userAgentString, logger: CreateLogger(config)}, nil
return &SIPCallServer{config: moduleConfig, IP: ipString, Port: int(portNum), Transport: transportString, UserAgent: userAgentString, logger: CreateLogger(moduleConfig)}, nil
},
})
}

View File

@@ -46,66 +46,49 @@ type SIPDTMFCall struct {
func init() {
RegisterModule(ModuleRegistration{
Type: "sip.dtmf.server",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
portNum := 5060
New: func(moduleConfig config.ModuleConfig) (Module, error) {
params := moduleConfig.Params
port, ok := params["port"]
if ok {
specificPortNum, ok := port.(float64)
portNum, err := params.GetInt("port")
if err != nil {
if !ok {
return nil, errors.New("sip.dtmf.server port must be a number")
if errors.Is(err, config.ErrParamNotFound) {
portNum = 5060
} else {
return nil, fmt.Errorf("sip.dtmf.server port error: %w", err)
}
portNum = int(specificPortNum)
}
ipString := "0.0.0.0"
ip, ok := params["ip"]
if ok {
specificIpString, ok := ip.(string)
if !ok {
return nil, errors.New("sip.dtmf.server ip must be a string")
ipString, err := params.GetString("ip")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
ipString = "0.0.0.0"
} else {
return nil, fmt.Errorf("sip.dtmf.server ip error: %w", err)
}
ipString = specificIpString
}
transportString := "udp"
transport, ok := params["transport"]
if ok {
specificTransportString, ok := transport.(string)
if !ok {
return nil, errors.New("sip.dtmf.server transport must be a string")
transportString, err := params.GetString("transport")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
transportString = "udp"
} else {
return nil, fmt.Errorf("sip.dtmf.server transport error: %w", err)
}
transportString = specificTransportString
}
userAgentString := "showbridge"
userAgent, ok := params["userAgent"]
if ok {
specificUserAgentString, ok := userAgent.(string)
if !ok {
return nil, errors.New("sip.dtmf.server userAgent must be a string")
userAgentString, err := params.GetString("userAgent")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
userAgentString = "showbridge"
} else {
return nil, fmt.Errorf("sip.dtmf.server userAgent error: %w", err)
}
userAgentString = specificUserAgentString
}
separator, ok := params["separator"]
if !ok {
return nil, errors.New("sip.dtmf.server requires a separator parameter")
}
separatorString, ok := separator.(string)
if !ok {
return nil, errors.New("sip.dtmf.server separator must be a string")
separatorString, err := params.GetString("separator")
if err != nil {
return nil, fmt.Errorf("sip.dtmf.server separator error: %w", err)
}
if len(separatorString) != 1 {
@@ -115,7 +98,7 @@ func init() {
if !strings.ContainsRune("0123456789*#ABCD", rune(separatorString[0])) {
return nil, errors.New("sip.dtmf.server separator must be a valid DTMF character")
}
return &SIPDTMFServer{config: config, IP: ipString, Port: int(portNum), Transport: transportString, UserAgent: userAgentString, Separator: separatorString, logger: CreateLogger(config)}, nil
return &SIPDTMFServer{config: moduleConfig, IP: ipString, Port: int(portNum), Transport: transportString, UserAgent: userAgentString, Separator: separatorString, logger: CreateLogger(moduleConfig)}, nil
},
})
}

View File

@@ -29,27 +29,14 @@ func init() {
Type: "net.tcp.client",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
host, ok := params["host"]
if !ok {
return nil, errors.New("net.tcp.client requires a host parameter")
hostString, err := params.GetString("host")
if err != nil {
return nil, fmt.Errorf("net.tcp.client host error: %w", err)
}
hostString, ok := host.(string)
if !ok {
return nil, errors.New("net.tcp.client host must be a string")
}
port, ok := params["port"]
if !ok {
return nil, errors.New("net.tcp.client requires a port parameter")
}
portNum, ok := port.(float64)
if !ok {
return nil, errors.New("net.tcp.client port must be a number")
portNum, err := params.GetInt("port")
if err != nil {
return nil, fmt.Errorf("net.tcp.client port error: %w", err)
}
addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", hostString, uint16(portNum)))
@@ -57,22 +44,15 @@ func init() {
return nil, err
}
framingMethod, ok := params["framing"]
if !ok {
return nil, errors.New("net.tcp.client requires a framing parameter")
}
framingMethodString, ok := framingMethod.(string)
if !ok {
return nil, errors.New("net.tcp.client framing method must be a string")
framingMethodString, err := params.GetString("framing")
if err != nil {
return nil, fmt.Errorf("net.tcp.client framing error: %w", err)
}
framer := framer.GetFramer(framingMethodString)
if framer == nil {
return nil, fmt.Errorf("net.tcp.client unknown framing method: %s", framingMethod)
return nil, fmt.Errorf("net.tcp.client unknown framing method: %s", framingMethodString)
}
return &TCPClient{framer: framer, Addr: addr, config: config, logger: CreateLogger(config)}, nil
},

View File

@@ -33,55 +33,38 @@ type TCPServer struct {
func init() {
RegisterModule(ModuleRegistration{
Type: "net.tcp.server",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
port, ok := params["port"]
if !ok {
return nil, errors.New("net.tcp.server requires a port parameter")
New: func(moduleConfig config.ModuleConfig) (Module, error) {
params := moduleConfig.Params
portNum, err := params.GetInt("port")
if err != nil {
return nil, fmt.Errorf("net.tcp.server port error: %w", err)
}
portNum, ok := port.(float64)
if !ok {
return nil, errors.New("net.tcp.server port must be a number")
}
framingMethod, ok := params["framing"]
if !ok {
return nil, errors.New("net.tcp.server requires a framing parameter")
}
framingMethodString, ok := framingMethod.(string)
if !ok {
return nil, errors.New("net.tcp.server framing method must be a string")
framingMethodString, err := params.GetString("framing")
if err != nil {
return nil, fmt.Errorf("net.tcp.server framing error: %w", err)
}
framer := framer.GetFramer(framingMethodString)
if framer == nil {
return nil, fmt.Errorf("net.tcp.server unknown framing method: %s", framingMethod)
return nil, fmt.Errorf("net.tcp.server unknown framing method: %s", framingMethodString)
}
ipString := "0.0.0.0"
ip, ok := params["ip"]
if ok {
specificIpString, ok := ip.(string)
if !ok {
return nil, errors.New("net.tcp.server ip must be a string")
ipString, err := params.GetString("ip")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
ipString = "0.0.0.0"
} else {
return nil, fmt.Errorf("net.tcp.server ip error: %w", err)
}
ipString = specificIpString
}
addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ipString, uint16(portNum)))
if err != nil {
return nil, err
}
return &TCPServer{Framer: framer, Addr: addr, config: config, quit: make(chan interface{}), logger: CreateLogger(config)}, nil
return &TCPServer{Framer: framer, Addr: addr, config: moduleConfig, quit: make(chan interface{}), logger: CreateLogger(moduleConfig)}, nil
},
})
}

View File

@@ -43,12 +43,12 @@ func TestBadHTTPServer(t *testing.T) {
{
name: "no port param",
params: map[string]any{},
errorString: "http.server requires a port parameter",
errorString: "http.server port error: not found",
},
{
name: "non-numeric port",
params: map[string]any{"port": "3000"},
errorString: "http.server port must be a number",
errorString: "http.server port error: not a number",
},
}

View File

@@ -43,12 +43,12 @@ func TestBadMIDIInput(t *testing.T) {
{
name: "no port param",
params: map[string]any{},
errorString: "midi.input requires a port parameter",
errorString: "midi.input port error: not found",
},
{
name: "non-string port",
params: map[string]any{"port": 123},
errorString: "midi.input port must be a string",
errorString: "midi.input port error: not a string",
},
}

View File

@@ -43,12 +43,12 @@ func TestBadMIDIOutput(t *testing.T) {
{
name: "no port param",
params: map[string]any{},
errorString: "midi.output requires a port parameter",
errorString: "midi.output port error: not found",
},
{
name: "non-string port",
params: map[string]any{"port": 123},
errorString: "midi.output port must be a string",
errorString: "midi.output port error: not a string",
},
}

View File

@@ -48,7 +48,7 @@ func TestBadMQTTClient(t *testing.T) {
"topic": "test/topic",
"clientId": "test",
},
errorString: "mqtt.client requires a broker parameter",
errorString: "mqtt.client broker error: not found",
},
{
name: "non-string broker",
@@ -57,7 +57,7 @@ func TestBadMQTTClient(t *testing.T) {
"topic": "test/topic",
"clientId": "test",
},
errorString: "mqtt.client broker must be a string",
errorString: "mqtt.client broker error: not a string",
},
{
name: "no topic param",
@@ -65,7 +65,7 @@ func TestBadMQTTClient(t *testing.T) {
"broker": "mqtt://localhost:1883",
"clientId": "test",
},
errorString: "mqtt.client requires a topic parameter",
errorString: "mqtt.client topic error: not found",
},
{
name: "non-string topic",
@@ -74,7 +74,7 @@ func TestBadMQTTClient(t *testing.T) {
"topic": 123,
"clientId": "test",
},
errorString: "mqtt.client topic must be a string",
errorString: "mqtt.client topic error: not a string",
},
{
name: "no clientId param",
@@ -82,7 +82,7 @@ func TestBadMQTTClient(t *testing.T) {
"broker": "mqtt://localhost:1883",
"topic": "test/topic",
},
errorString: "mqtt.client requires a clientId parameter",
errorString: "mqtt.client clientId error: not found",
},
{
name: "non-string clientId",
@@ -91,7 +91,7 @@ func TestBadMQTTClient(t *testing.T) {
"topic": "test/topic",
"clientId": 123,
},
errorString: "mqtt.client clientId must be a string",
errorString: "mqtt.client clientId error: not a string",
},
}

View File

@@ -46,7 +46,7 @@ func TestBadNATSClient(t *testing.T) {
params: map[string]any{
"subject": "test/subject",
},
errorString: "nats.client requires a url parameter",
errorString: "nats.client url error: not found",
},
{
name: "non-string url",
@@ -54,14 +54,14 @@ func TestBadNATSClient(t *testing.T) {
"url": 123,
"subject": "test/subject",
},
errorString: "nats.client url must be a string",
errorString: "nats.client url error: not a string",
},
{
name: "no subject param",
params: map[string]any{
"url": "nats://127.0.0.1:4222",
},
errorString: "nats.client requires a subject parameter",
errorString: "nats.client subject error: not found",
},
{
name: "non-string subject",
@@ -69,7 +69,7 @@ func TestBadNATSClient(t *testing.T) {
"url": "nats://127.0.0.1:4222",
"subject": 123,
},
errorString: "nats.client subject must be a string",
errorString: "nats.client subject error: not a string",
},
}

View File

@@ -46,7 +46,7 @@ func TestBadNATSServer(t *testing.T) {
params: map[string]any{
"ip": 123,
},
errorString: "nats.server ip must be a string",
errorString: "nats.server ip error: not a string",
},
}

View File

@@ -47,7 +47,7 @@ func TestBadSerialClient(t *testing.T) {
params: map[string]any{
"framing": "LF",
},
errorString: "serial.client requires a port parameter",
errorString: "serial.client port error: not found",
},
{
name: "non-string port param",
@@ -55,14 +55,14 @@ func TestBadSerialClient(t *testing.T) {
"port": 8000,
"framing": "LF",
},
errorString: "serial.client port must be a string",
errorString: "serial.client port error: not a string",
},
{
name: "no framing param",
params: map[string]any{
"port": "/dev/ttyUSB0",
},
errorString: "serial.client requires a framing parameter",
errorString: "serial.client framing error: not found",
},
{
name: "non-string framing param",
@@ -70,7 +70,7 @@ func TestBadSerialClient(t *testing.T) {
"port": "/dev/ttyUSB0",
"framing": 1,
},
errorString: "serial.client framing method must be a string",
errorString: "serial.client framing error: not a string",
},
{
name: "unkown framing method",

View File

@@ -42,28 +42,28 @@ func TestBadSIPCallServer(t *testing.T) {
params: map[string]any{
"port": "8000",
},
errorString: "sip.call.server port must be a number",
errorString: "sip.call.server port error: not a number",
},
{
name: "non-string ip param",
params: map[string]any{
"ip": 123,
},
errorString: "sip.call.server ip must be a string",
errorString: "sip.call.server ip error: not a string",
},
{
name: "non-string transport param",
params: map[string]any{
"transport": 123,
},
errorString: "sip.call.server transport must be a string",
errorString: "sip.call.server transport error: not a string",
},
{
name: "non-string userAgent param",
params: map[string]any{
"userAgent": 123,
},
errorString: "sip.call.server userAgent must be a string",
errorString: "sip.call.server userAgent error: not a string",
},
}

View File

@@ -43,14 +43,14 @@ func TestBadSIPDTMFServer(t *testing.T) {
{
name: "no separator param",
params: map[string]any{},
errorString: "sip.dtmf.server requires a separator parameter",
errorString: "sip.dtmf.server separator error: not found",
},
{
name: "non-string separator param",
params: map[string]any{
"separator": 123,
},
errorString: "sip.dtmf.server separator must be a string",
errorString: "sip.dtmf.server separator error: not a string",
},
{
name: "non-number port param",
@@ -58,7 +58,7 @@ func TestBadSIPDTMFServer(t *testing.T) {
"separator": "#",
"port": "8000",
},
errorString: "sip.dtmf.server port must be a number",
errorString: "sip.dtmf.server port error: not a number",
},
{
name: "non-string ip param",
@@ -66,7 +66,7 @@ func TestBadSIPDTMFServer(t *testing.T) {
"separator": "#",
"ip": 123,
},
errorString: "sip.dtmf.server ip must be a string",
errorString: "sip.dtmf.server ip error: not a string",
},
{
name: "non-string transport param",
@@ -74,7 +74,7 @@ func TestBadSIPDTMFServer(t *testing.T) {
"separator": "#",
"transport": 123,
},
errorString: "sip.dtmf.server transport must be a string",
errorString: "sip.dtmf.server transport error: not a string",
},
{
name: "non-string userAgent param",
@@ -82,7 +82,7 @@ func TestBadSIPDTMFServer(t *testing.T) {
"separator": "#",
"userAgent": 123,
},
errorString: "sip.dtmf.server userAgent must be a string",
errorString: "sip.dtmf.server userAgent error: not a string",
},
}

View File

@@ -47,7 +47,7 @@ func TestBadTCPClient(t *testing.T) {
params: map[string]any{
"host": "localhost",
},
errorString: "net.tcp.client requires a port parameter",
errorString: "net.tcp.client port error: not found",
},
{
name: "non-number port param",
@@ -55,14 +55,14 @@ func TestBadTCPClient(t *testing.T) {
"host": "localhost",
"port": "8000",
},
errorString: "net.tcp.client port must be a number",
errorString: "net.tcp.client port error: not a number",
},
{
name: "no host param",
params: map[string]any{
"port": 8000.0,
},
errorString: "net.tcp.client requires a host parameter",
errorString: "net.tcp.client host error: not found",
},
{
name: "non-string host param",
@@ -70,7 +70,7 @@ func TestBadTCPClient(t *testing.T) {
"host": 123,
"port": 8000.0,
},
errorString: "net.tcp.client host must be a string",
errorString: "net.tcp.client host error: not a string",
},
}

View File

@@ -46,7 +46,7 @@ func TestBadTCPServer(t *testing.T) {
params: map[string]any{
"framing": "LF",
},
errorString: "net.tcp.server requires a port parameter",
errorString: "net.tcp.server port error: not found",
},
{
name: "non-number port param",
@@ -54,14 +54,14 @@ func TestBadTCPServer(t *testing.T) {
"port": "8000",
"framing": "LF",
},
errorString: "net.tcp.server port must be a number",
errorString: "net.tcp.server port error: not a number",
},
{
name: "no framing param",
params: map[string]any{
"port": 8000.0,
},
errorString: "net.tcp.server requires a framing parameter",
errorString: "net.tcp.server framing error: not found",
},
{
name: "non-string framing param",
@@ -69,7 +69,7 @@ func TestBadTCPServer(t *testing.T) {
"port": 8000.0,
"framing": 1,
},
errorString: "net.tcp.server framing method must be a string",
errorString: "net.tcp.server framing error: not a string",
},
{
name: "unkown framing method",
@@ -86,7 +86,7 @@ func TestBadTCPServer(t *testing.T) {
"framing": "LF",
"ip": 123,
},
errorString: "net.tcp.server ip must be a string",
errorString: "net.tcp.server ip error: not a string",
},
{
name: "invalid addr",

View File

@@ -43,14 +43,14 @@ func TestBadTimeInterval(t *testing.T) {
{
name: "no duration param",
params: map[string]any{},
errorString: "time.interval requires a duration parameter",
errorString: "time.interval duration error: not found",
},
{
name: "non-number duration param",
params: map[string]any{
"duration": "8000",
},
errorString: "time.interval duration must be a number",
errorString: "time.interval duration error: not a number",
},
}

View File

@@ -43,14 +43,14 @@ func TestBadTimeTimer(t *testing.T) {
{
name: "no duration param",
params: map[string]any{},
errorString: "time.timer requires a duration parameter",
errorString: "time.timer duration error: not found",
},
{
name: "non-number duration param",
params: map[string]any{
"duration": "8000",
},
errorString: "time.timer duration must be a number",
errorString: "time.timer duration error: not a number",
},
}

View File

@@ -47,7 +47,7 @@ func TestBadUDPClient(t *testing.T) {
params: map[string]any{
"host": "localhost",
},
errorString: "net.udp.client requires a port parameter",
errorString: "net.udp.client port error: not found",
},
{
name: "non-number port param",
@@ -55,14 +55,14 @@ func TestBadUDPClient(t *testing.T) {
"host": "localhost",
"port": "8000",
},
errorString: "net.udp.client port must be a number",
errorString: "net.udp.client port error: not a number",
},
{
name: "no host param",
params: map[string]any{
"port": 8000.0,
},
errorString: "net.udp.client requires a host parameter",
errorString: "net.udp.client host error: not found",
},
{
name: "non-string host param",
@@ -70,7 +70,7 @@ func TestBadUDPClient(t *testing.T) {
"host": 123,
"port": 8000.0,
},
errorString: "net.udp.client host must be a string",
errorString: "net.udp.client host error: not a string",
},
}

View File

@@ -46,7 +46,7 @@ func TestBadUDPMulticast(t *testing.T) {
params: map[string]any{
"ip": "localhost",
},
errorString: "net.udp.multicast requires a port parameter",
errorString: "net.udp.multicast port error: not found",
},
{
name: "non-number port param",
@@ -54,14 +54,14 @@ func TestBadUDPMulticast(t *testing.T) {
"ip": "localhost",
"port": "8000",
},
errorString: "net.udp.multicast port must be a number",
errorString: "net.udp.multicast port error: not a number",
},
{
name: "no ip param",
params: map[string]any{
"port": 8000.0,
},
errorString: "net.udp.multicast requires an ip parameter",
errorString: "net.udp.multicast ip error: not found",
},
{
name: "non-string ip param",
@@ -69,7 +69,7 @@ func TestBadUDPMulticast(t *testing.T) {
"ip": 123,
"port": 8000.0,
},
errorString: "net.udp.multicast ip must be a string",
errorString: "net.udp.multicast ip error: not a string",
},
{
name: "invalid addr",

View File

@@ -43,14 +43,14 @@ func TestBadUDPServer(t *testing.T) {
{
name: "no port param",
params: map[string]any{},
errorString: "net.udp.server requires a port parameter",
errorString: "net.udp.server port error: not found",
},
{
name: "non-number port param",
params: map[string]any{
"port": "8000",
},
errorString: "net.udp.server port must be a number",
errorString: "net.udp.server port error: not a number",
},
{
name: "non-string ip param",
@@ -58,7 +58,7 @@ func TestBadUDPServer(t *testing.T) {
"port": 8000.0,
"ip": 123,
},
errorString: "net.udp.server ip must be a string",
errorString: "net.udp.server ip error: not a string",
},
{
name: "non-number bufferSize param",
@@ -66,7 +66,7 @@ func TestBadUDPServer(t *testing.T) {
"port": 8000.0,
"bufferSize": "1024",
},
errorString: "net.udp.server bufferSize must be a number",
errorString: "net.udp.server bufferSize error: not a number",
},
{
name: "invalid addr",

View File

@@ -3,6 +3,7 @@ package module
import (
"context"
"errors"
"fmt"
"log/slog"
"time"
@@ -26,17 +27,11 @@ func init() {
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
duration, ok := params["duration"]
if !ok {
return nil, errors.New("time.interval requires a duration parameter")
durationInt, err := params.GetInt("duration")
if err != nil {
return nil, fmt.Errorf("time.interval duration error: %w", err)
}
durationNum, ok := duration.(float64)
if !ok {
return nil, errors.New("time.interval duration must be a number")
}
return &TimeInterval{Duration: uint32(durationNum), config: config, logger: CreateLogger(config)}, nil
return &TimeInterval{Duration: uint32(durationInt), config: config, logger: CreateLogger(config)}, nil
},
})
}

View File

@@ -3,6 +3,7 @@ package module
import (
"context"
"errors"
"fmt"
"log/slog"
"time"
@@ -26,15 +27,9 @@ func init() {
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
duration, ok := params["duration"]
if !ok {
return nil, errors.New("time.timer requires a duration parameter")
}
durationNum, ok := duration.(float64)
if !ok {
return nil, errors.New("time.timer duration must be a number")
durationNum, err := params.GetInt("duration")
if err != nil {
return nil, fmt.Errorf("time.timer duration error: %w", err)
}
return &TimeTimer{Duration: uint32(durationNum), config: config, logger: CreateLogger(config)}, nil

View File

@@ -27,27 +27,14 @@ func init() {
Type: "net.udp.client",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
host, ok := params["host"]
if !ok {
return nil, errors.New("net.udp.client requires a host parameter")
hostString, err := params.GetString("host")
if err != nil {
return nil, fmt.Errorf("net.udp.client host error: %w", err)
}
hostString, ok := host.(string)
if !ok {
return nil, errors.New("net.udp.client host must be a string")
}
port, ok := params["port"]
if !ok {
return nil, errors.New("net.udp.client requires a port parameter")
}
portNum, ok := port.(float64)
if !ok {
return nil, errors.New("net.udp.client port must be a number")
portNum, err := params.GetInt("port")
if err != nil {
return nil, fmt.Errorf("net.udp.client port error: %w", err)
}
addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", hostString, uint16(portNum)))

View File

@@ -25,36 +25,23 @@ type UDPMulticast struct {
func init() {
RegisterModule(ModuleRegistration{
Type: "net.udp.multicast",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
ip, ok := params["ip"]
if !ok {
return nil, errors.New("net.udp.multicast requires an ip parameter")
New: func(moduleConfig config.ModuleConfig) (Module, error) {
params := moduleConfig.Params
ipString, err := params.GetString("ip")
if err != nil {
return nil, fmt.Errorf("net.udp.multicast ip error: %w", err)
}
ipString, ok := ip.(string)
if !ok {
return nil, errors.New("net.udp.multicast ip must be a string")
}
port, ok := params["port"]
if !ok {
return nil, errors.New("net.udp.multicast requires a port parameter")
}
portNum, ok := port.(float64)
if !ok {
return nil, errors.New("net.udp.multicast port must be a number")
portNum, err := params.GetInt("port")
if err != nil {
return nil, fmt.Errorf("net.udp.multicast port error: %w", err)
}
addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", ipString, uint16(portNum)))
if err != nil {
return nil, err
}
return &UDPMulticast{config: config, Addr: addr, logger: CreateLogger(config)}, nil
return &UDPMulticast{config: moduleConfig, Addr: addr, logger: CreateLogger(moduleConfig)}, nil
},
})
}

View File

@@ -25,30 +25,20 @@ type UDPServer struct {
func init() {
RegisterModule(ModuleRegistration{
Type: "net.udp.server",
New: func(config config.ModuleConfig) (Module, error) {
params := config.Params
port, ok := params["port"]
if !ok {
return nil, errors.New("net.udp.server requires a port parameter")
New: func(moduleConfig config.ModuleConfig) (Module, error) {
params := moduleConfig.Params
portNum, err := params.GetInt("port")
if err != nil {
return nil, fmt.Errorf("net.udp.server port error: %w", err)
}
portNum, ok := port.(float64)
if !ok {
return nil, errors.New("net.udp.server port must be a number")
}
ipString := "0.0.0.0"
ip, ok := params["ip"]
if ok {
specificIpString, ok := ip.(string)
if !ok {
return nil, errors.New("net.udp.server ip must be a string")
ipString, err := params.GetString("ip")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
ipString = "0.0.0.0"
} else {
return nil, fmt.Errorf("net.udp.server ip error: %w", err)
}
ipString = specificIpString
}
addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", ipString, uint16(portNum)))
@@ -56,18 +46,15 @@ func init() {
return nil, err
}
bufferSizeNum := 2048
bufferSize, ok := params["bufferSize"]
if ok {
bufferSizeFloat, ok := bufferSize.(float64)
if !ok {
return nil, errors.New("net.udp.server bufferSize must be a number")
bufferSizeNum, err := params.GetInt("bufferSize")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
bufferSizeNum = 2048
} else {
return nil, fmt.Errorf("net.udp.server bufferSize error: %w", err)
}
bufferSizeNum = int(bufferSizeFloat)
}
return &UDPServer{Addr: addr, BufferSize: bufferSizeNum, config: config, logger: CreateLogger(config)}, nil
return &UDPServer{Addr: addr, BufferSize: bufferSizeNum, config: moduleConfig, logger: CreateLogger(moduleConfig)}, nil
},
})
}

View File

@@ -37,13 +37,9 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
opCode, ok := params["opCode"]
if !ok {
return nil, fmt.Errorf("artnet.packet.filter requires an opCode parameter")
}
opCodeNum, ok := opCode.(float64)
if !ok {
return nil, fmt.Errorf("artnet.packet.filter opCode must be a number")
opCodeNum, err := params.GetInt("opCode")
if err != nil {
return nil, fmt.Errorf("artnet.packet.filter opCode error: %w", err)
}
return &ArtNetPacketFilter{config: config, OpCode: uint16(opCodeNum)}, nil

View File

@@ -3,6 +3,7 @@ package processor
import (
"context"
"errors"
"fmt"
"strconv"
"github.com/jwetzell/showbridge-go/internal/config"
@@ -34,20 +35,18 @@ func (fp *FloatParse) Type() string {
func init() {
RegisterProcessor(ProcessorRegistration{
Type: "float.parse",
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
bitSizeNum := 64
bitSize, ok := params["bitSize"]
if ok {
bitSizeFloat, ok := bitSize.(float64)
New: func(moduleConfig config.ProcessorConfig) (Processor, error) {
params := moduleConfig.Params
if !ok {
return nil, errors.New("float.parse bitSize must be a number")
bitSizeNum, err := params.GetInt("bitSize")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
bitSizeNum = 64
} else {
return nil, fmt.Errorf("float.parse bitSize error: %w", err)
}
bitSizeNum = int(bitSizeFloat)
}
return &FloatParse{config: config, BitSize: bitSizeNum}, nil
return &FloatParse{config: moduleConfig, BitSize: bitSizeNum}, nil
},
})
}

View File

@@ -3,7 +3,7 @@ package processor
import (
"bytes"
"context"
"errors"
"fmt"
"strconv"
"text/template"
@@ -187,16 +187,9 @@ func init() {
// TODO(jwetzell): make some params optional
params := config.Params
id, ok := params["id"]
if !ok {
return nil, errors.New("freed.create requires an id parameter")
}
idString, ok := id.(string)
if !ok {
return nil, errors.New("freed.create id must be a string")
idString, err := params.GetString("id")
if err != nil {
return nil, fmt.Errorf("freed.create id error: %w", err)
}
idTemplate, err := template.New("id").Parse(idString)
@@ -205,44 +198,23 @@ func init() {
return nil, err
}
pan, ok := params["pan"]
if !ok {
return nil, errors.New("freed.create requires a pan parameter")
}
panString, ok := pan.(string)
if !ok {
return nil, errors.New("freed.create pan must be a string")
panString, err := params.GetString("pan")
if err != nil {
return nil, fmt.Errorf("freed.create pan error: %w", err)
}
panTemplate, err := template.New("pan").Parse(panString)
tilt, ok := params["tilt"]
if !ok {
return nil, errors.New("freed.create requires a tilt parameter")
}
tiltString, ok := tilt.(string)
if !ok {
return nil, errors.New("freed.create tilt must be a string")
tiltString, err := params.GetString("tilt")
if err != nil {
return nil, fmt.Errorf("freed.create tilt error: %w", err)
}
tiltTemplate, err := template.New("tilt").Parse(tiltString)
roll, ok := params["roll"]
if !ok {
return nil, errors.New("freed.create requires a roll parameter")
}
rollString, ok := roll.(string)
if !ok {
return nil, errors.New("freed.create roll must be a string")
rollString, err := params.GetString("roll")
if err != nil {
return nil, fmt.Errorf("freed.create roll error: %w", err)
}
rollTemplate, err := template.New("roll").Parse(rollString)
@@ -251,16 +223,9 @@ func init() {
return nil, err
}
posX, ok := params["posX"]
if !ok {
return nil, errors.New("freed.create requires a posX parameter")
}
posXString, ok := posX.(string)
if !ok {
return nil, errors.New("freed.create posX must be a string")
posXString, err := params.GetString("posX")
if err != nil {
return nil, fmt.Errorf("freed.create posX error: %w", err)
}
posXTemplate, err := template.New("posX").Parse(posXString)
@@ -269,16 +234,9 @@ func init() {
return nil, err
}
posY, ok := params["posY"]
if !ok {
return nil, errors.New("freed.create requires a posY parameter")
}
posYString, ok := posY.(string)
if !ok {
return nil, errors.New("freed.create posY must be a string")
posYString, err := params.GetString("posY")
if err != nil {
return nil, fmt.Errorf("freed.create posY error: %w", err)
}
posYTemplate, err := template.New("posY").Parse(posYString)
@@ -287,16 +245,9 @@ func init() {
return nil, err
}
posZ, ok := params["posZ"]
if !ok {
return nil, errors.New("freed.create requires a posZ parameter")
}
posZString, ok := posZ.(string)
if !ok {
return nil, errors.New("freed.create posZ must be a string")
posZString, err := params.GetString("posZ")
if err != nil {
return nil, fmt.Errorf("freed.create posZ error: %w", err)
}
posZTemplate, err := template.New("posZ").Parse(posZString)
@@ -305,30 +256,16 @@ func init() {
return nil, err
}
zoom, ok := params["zoom"]
if !ok {
return nil, errors.New("freed.create requires a zoom parameter")
}
zoomString, ok := zoom.(string)
if !ok {
return nil, errors.New("freed.create zoom must be a string")
zoomString, err := params.GetString("zoom")
if err != nil {
return nil, fmt.Errorf("freed.create zoom error: %w", err)
}
zoomTemplate, err := template.New("zoom").Parse(zoomString)
focus, ok := params["focus"]
if !ok {
return nil, errors.New("freed.create requires a focus parameter")
}
focusString, ok := focus.(string)
if !ok {
return nil, errors.New("freed.create focus must be a string")
focusString, err := params.GetString("focus")
if err != nil {
return nil, fmt.Errorf("freed.create focus error: %w", err)
}
focusTemplate, err := template.New("focus").Parse(focusString)

View File

@@ -3,7 +3,7 @@ package processor
import (
"bytes"
"context"
"errors"
"fmt"
"net/http"
"text/template"
@@ -47,28 +47,14 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
method, ok := params["method"]
if !ok {
return nil, errors.New("http.request.create requires a method parameter")
methodString, err := params.GetString("method")
if err != nil {
return nil, fmt.Errorf("http.request.create method error: %w", err)
}
methodString, ok := method.(string)
if !ok {
return nil, errors.New("http.request.create url must be a string")
}
url, ok := params["url"]
if !ok {
return nil, errors.New("http.request.create requires a url parameter")
}
urlString, ok := url.(string)
if !ok {
return nil, errors.New("http.request.create url must be a string")
urlString, err := params.GetString("url")
if err != nil {
return nil, fmt.Errorf("http.request.create url error: %w", err)
}
urlTemplate, err := template.New("url").Parse(urlString)

View File

@@ -44,18 +44,11 @@ func (hrf *HTTPRequestFilter) Type() string {
func init() {
RegisterProcessor(ProcessorRegistration{
Type: "http.request.filter",
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
path, ok := params["path"]
if !ok {
return nil, errors.New("http.request.filter requires a path parameter")
}
pathString, ok := path.(string)
if !ok {
return nil, errors.New("http.request.filter path must be a string")
New: func(moduleConfig config.ProcessorConfig) (Processor, error) {
params := moduleConfig.Params
pathString, err := params.GetString("path")
if err != nil {
return nil, fmt.Errorf("http.request.filter path error: %w", err)
}
pathRegexp, err := regexp.Compile(fmt.Sprintf("^%s$", pathString))
@@ -64,18 +57,17 @@ func init() {
return nil, err
}
method, ok := params["method"]
if ok {
methodString, ok := method.(string)
if !ok {
return nil, errors.New("http.request.filter method must be a string")
methodString, err := params.GetString("method")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
return &HTTPRequestFilter{config: moduleConfig, Path: pathRegexp}, nil
} else {
return nil, fmt.Errorf("http.request.filter method error: %w", err)
}
return &HTTPRequestFilter{config: config, Path: pathRegexp, Method: methodString}, nil
}
return &HTTPRequestFilter{config: config, Path: pathRegexp}, nil
return &HTTPRequestFilter{config: moduleConfig, Path: pathRegexp, Method: methodString}, nil
},
})
}

View File

@@ -3,7 +3,7 @@ package processor
import (
"bytes"
"context"
"errors"
"fmt"
"text/template"
"github.com/jwetzell/showbridge-go/internal/config"
@@ -44,28 +44,14 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
status, ok := params["status"]
if !ok {
return nil, errors.New("http.response.create requires a status parameter")
statusNum, err := params.GetInt("status")
if err != nil {
return nil, fmt.Errorf("http.response.create status error: %w", err)
}
statusNum, ok := status.(float64)
if !ok {
return nil, errors.New("http.response.create status must be a number")
}
bodyTmpl, ok := params["bodyTemplate"]
if !ok {
return nil, errors.New("http.response.create requires a bodyTemplate parameter")
}
bodyTemplateString, ok := bodyTmpl.(string)
if !ok {
return nil, errors.New("http.response.create bodyTemplate must be a string")
bodyTemplateString, err := params.GetString("bodyTemplate")
if err != nil {
return nil, fmt.Errorf("http.response.create bodyTemplate error: %w", err)
}
bodyTemplate, err := template.New("body").Parse(bodyTemplateString)

View File

@@ -3,6 +3,7 @@ package processor
import (
"context"
"errors"
"fmt"
"strconv"
"github.com/jwetzell/showbridge-go/internal/config"
@@ -35,33 +36,27 @@ func (ip *IntParse) Type() string {
func init() {
RegisterProcessor(ProcessorRegistration{
Type: "int.parse",
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
New: func(moduleConfig config.ProcessorConfig) (Processor, error) {
params := moduleConfig.Params
baseNum := 10
base, ok := params["base"]
if ok {
baseFloat, ok := base.(float64)
if !ok {
return nil, errors.New("int.parse base must be a number")
baseNum, err := params.GetInt("base")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
baseNum = 10
} else {
return nil, fmt.Errorf("int.parse base error: %w", err)
}
baseNum = int(baseFloat)
}
bitSizeNum := 64
bitSize, ok := params["bitSize"]
if ok {
bitSizeFloat, ok := bitSize.(float64)
if !ok {
return nil, errors.New("int.parse bitSize must be a number")
bitSizeNum, err := params.GetInt("bitSize")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
bitSizeNum = 64
} else {
return nil, fmt.Errorf("int.parse bitSize error: %w", err)
}
bitSizeNum = int(bitSizeFloat)
}
return &IntParse{config: config, Base: baseNum, BitSize: bitSizeNum}, nil
return &IntParse{config: moduleConfig, Base: baseNum, BitSize: bitSizeNum}, nil
},
})
}

View File

@@ -3,6 +3,7 @@ package processor
import (
"context"
"errors"
"fmt"
"math/rand/v2"
"github.com/jwetzell/showbridge-go/internal/config"
@@ -29,33 +30,21 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
min, ok := params["min"]
if !ok {
return nil, errors.New("int.random requires a min parameter")
minInt, err := params.GetInt("min")
if err != nil {
return nil, fmt.Errorf("int.random min error: %w", err)
}
minFloat, ok := min.(float64)
if !ok {
return nil, errors.New("int.random min must be a number")
maxInt, err := params.GetInt("max")
if err != nil {
return nil, fmt.Errorf("int.random max error: %w", err)
}
max, ok := params["max"]
if !ok {
return nil, errors.New("int.random requires a max parameter")
}
maxFloat, ok := max.(float64)
if !ok {
return nil, errors.New("int.random max must be a number")
}
if maxFloat < minFloat {
if maxInt < minInt {
return nil, errors.New("int.random max must be greater than min")
}
return &IntRandom{config: config, Min: int(minFloat), Max: int(maxFloat)}, nil
return &IntRandom{config: config, Min: int(minInt), Max: int(maxInt)}, nil
},
})
}

View File

@@ -5,7 +5,6 @@ package processor
import (
"bytes"
"context"
"errors"
"fmt"
"strconv"
"text/template"
@@ -32,16 +31,9 @@ func newMidiNoteOnCreate(config config.ProcessorConfig) (Processor, error) {
params := config.Params
channel, ok := params["channel"]
if !ok {
return nil, errors.New("midi.message.create NoteOn requires a channel parameter")
}
channelString, ok := channel.(string)
if !ok {
return nil, errors.New("midi.message.create NoteOn channel must be a string")
channelString, err := params.GetString("channel")
if err != nil {
return nil, fmt.Errorf("midi.message.create channel error: %w", err)
}
channelTemplate, err := template.New("channel").Parse(channelString)
@@ -50,16 +42,9 @@ func newMidiNoteOnCreate(config config.ProcessorConfig) (Processor, error) {
return nil, err
}
note, ok := params["note"]
if !ok {
return nil, errors.New("midi.message.create NoteOn requires a note parameter")
}
noteString, ok := note.(string)
if !ok {
return nil, errors.New("midi.message.create NoteOn note must be a string")
noteString, err := params.GetString("note")
if err != nil {
return nil, fmt.Errorf("midi.message.create note error: %w", err)
}
noteTemplate, err := template.New("note").Parse(noteString)
@@ -68,16 +53,9 @@ func newMidiNoteOnCreate(config config.ProcessorConfig) (Processor, error) {
return nil, err
}
velocity, ok := params["velocity"]
if !ok {
return nil, errors.New("midi.message.create NoteOn requires a velocity parameter")
}
velocityString, ok := velocity.(string)
if !ok {
return nil, errors.New("midi.message.create NoteOn velocity must be a string")
velocityString, err := params.GetString("velocity")
if err != nil {
return nil, fmt.Errorf("midi.message.create velocity error: %w", err)
}
velocityTemplate, err := template.New("velocity").Parse(velocityString)
@@ -123,16 +101,9 @@ func newMidiNoteOffCreate(config config.ProcessorConfig) (Processor, error) {
params := config.Params
channel, ok := params["channel"]
if !ok {
return nil, errors.New("midi.message.create NoteOn requires a channel parameter")
}
channelString, ok := channel.(string)
if !ok {
return nil, errors.New("midi.message.create NoteOn channel must be a string")
channelString, err := params.GetString("channel")
if err != nil {
return nil, fmt.Errorf("midi.message.create channel error: %w", err)
}
channelTemplate, err := template.New("channel").Parse(channelString)
@@ -141,16 +112,9 @@ func newMidiNoteOffCreate(config config.ProcessorConfig) (Processor, error) {
return nil, err
}
note, ok := params["note"]
if !ok {
return nil, errors.New("midi.message.create NoteOn requires a note parameter")
}
noteString, ok := note.(string)
if !ok {
return nil, errors.New("midi.message.create NoteOn note must be a string")
noteString, err := params.GetString("note")
if err != nil {
return nil, fmt.Errorf("midi.message.create note error: %w", err)
}
noteTemplate, err := template.New("note").Parse(noteString)
@@ -159,6 +123,17 @@ func newMidiNoteOffCreate(config config.ProcessorConfig) (Processor, error) {
return nil, err
}
velocityString, err := params.GetString("velocity")
if err != nil {
return nil, fmt.Errorf("midi.message.create velocity error: %w", err)
}
velocityTemplate, err := template.New("velocity").Parse(velocityString)
if err != nil {
return nil, err
}
return &MIDIMessageCreate{config: config, ProcessFunc: func(ctx context.Context, payload any) (any, error) {
var channelBuffer bytes.Buffer
@@ -179,7 +154,16 @@ func newMidiNoteOffCreate(config config.ProcessorConfig) (Processor, error) {
noteValue, err := strconv.ParseUint(noteBuffer.String(), 10, 8)
payloadMessage := midi.NoteOff(uint8(channelValue), uint8(noteValue))
var velocityBuffer bytes.Buffer
err = velocityTemplate.Execute(&velocityBuffer, payload)
if err != nil {
return nil, err
}
velocityValue, err := strconv.ParseUint(velocityBuffer.String(), 10, 8)
payloadMessage := midi.NoteOffVelocity(uint8(channelValue), uint8(noteValue), uint8(velocityValue))
return payloadMessage, nil
}}, nil
}
@@ -188,16 +172,9 @@ func newMidiControlChangeCreate(config config.ProcessorConfig) (Processor, error
params := config.Params
channel, ok := params["channel"]
if !ok {
return nil, errors.New("midi.message.create ControlChange requires a channel parameter")
}
channelString, ok := channel.(string)
if !ok {
return nil, errors.New("midi.message.create ControlChange channel must be a string")
channelString, err := params.GetString("channel")
if err != nil {
return nil, fmt.Errorf("midi.message.create channel error: %w", err)
}
channelTemplate, err := template.New("channel").Parse(channelString)
@@ -206,16 +183,9 @@ func newMidiControlChangeCreate(config config.ProcessorConfig) (Processor, error
return nil, err
}
control, ok := params["control"]
if !ok {
return nil, errors.New("midi.message.create ControlChange requires a control parameter")
}
controlString, ok := control.(string)
if !ok {
return nil, errors.New("midi.message.create ControlChange control must be a string")
controlString, err := params.GetString("control")
if err != nil {
return nil, fmt.Errorf("midi.message.create control error: %w", err)
}
controlTemplate, err := template.New("control").Parse(controlString)
@@ -224,16 +194,9 @@ func newMidiControlChangeCreate(config config.ProcessorConfig) (Processor, error
return nil, err
}
value, ok := params["value"]
if !ok {
return nil, errors.New("midi.message.create ControlChange requires a value parameter")
}
valueString, ok := value.(string)
if !ok {
return nil, errors.New("midi.message.create ControlChange value must be a string")
valueString, err := params.GetString("value")
if err != nil {
return nil, fmt.Errorf("midi.message.create value error: %w", err)
}
valueTemplate, err := template.New("value").Parse(valueString)
@@ -280,16 +243,9 @@ func newMidiProgramChangeCreate(config config.ProcessorConfig) (Processor, error
params := config.Params
channel, ok := params["channel"]
if !ok {
return nil, errors.New("midi.message.create ProgramChange requires a channel parameter")
}
channelString, ok := channel.(string)
if !ok {
return nil, errors.New("midi.message.create ProgramChange channel must be a string")
channelString, err := params.GetString("channel")
if err != nil {
return nil, fmt.Errorf("midi.message.create channel error: %w", err)
}
channelTemplate, err := template.New("channel").Parse(channelString)
@@ -298,16 +254,9 @@ func newMidiProgramChangeCreate(config config.ProcessorConfig) (Processor, error
return nil, err
}
program, ok := params["program"]
if !ok {
return nil, errors.New("midi.message.create ProgramChange requires a program parameter")
}
programString, ok := program.(string)
if !ok {
return nil, errors.New("midi.message.create ProgramChange program must be a string")
programString, err := params.GetString("program")
if err != nil {
return nil, fmt.Errorf("midi.message.create program error: %w", err)
}
programTemplate, err := template.New("program").Parse(programString)
@@ -347,16 +296,9 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
msgType, ok := params["type"]
if !ok {
return nil, errors.New("midi.message.create requires a type parameter")
}
msgTypeString, ok := msgType.(string)
if !ok {
return nil, errors.New("midi.message.create type parameter must be a string")
msgTypeString, err := params.GetString("type")
if err != nil {
return nil, fmt.Errorf("midi.message.create type error: %w", err)
}
switch msgTypeString {

View File

@@ -5,6 +5,7 @@ package processor
import (
"context"
"errors"
"fmt"
"github.com/jwetzell/showbridge-go/internal/config"
"gitlab.com/gomidi/midi/v2"
@@ -38,18 +39,12 @@ func init() {
Type: "midi.message.filter",
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
midiType, ok := params["type"]
if !ok {
return nil, errors.New("midi.message.filter requires a type parameter")
}
midiTypeString, ok := midiType.(string)
if !ok {
return nil, errors.New("midi.message.filter type must be a string")
msgTypeString, err := params.GetString("type")
if err != nil {
return nil, fmt.Errorf("midi.message.filter type error: %w", err)
}
return &MIDIMessageFilter{config: config, MIDIType: midiTypeString}, nil
return &MIDIMessageFilter{config: config, MIDIType: msgTypeString}, nil
},
})
}

View File

@@ -3,6 +3,7 @@ package processor
import (
"context"
"errors"
"fmt"
"github.com/jwetzell/showbridge-go/internal/config"
)
@@ -81,47 +82,26 @@ func init() {
Type: "mqtt.message.create",
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
topic, ok := params["topic"]
if !ok {
return nil, errors.New("mqtt.message.create requires a topic parameter")
topicString, err := params.GetString("topic")
if err != nil {
return nil, fmt.Errorf("mqtt.message.create topic error: %w", err)
}
topicString, ok := topic.(string)
if !ok {
return nil, errors.New("mqtt.message.create topic must be a string")
qosByte, err := params.GetInt("qos")
if err != nil {
return nil, fmt.Errorf("mqtt.message.create qos error: %w", err)
}
qos, ok := params["qos"]
if !ok {
return nil, errors.New("mqtt.message.create requires a qos parameter")
}
qosByte, ok := qos.(float64)
if !ok {
return nil, errors.New("mqtt.message.create qos must be a number")
}
retained, ok := params["retained"]
if !ok {
return nil, errors.New("mqtt.message.create requires a retained parameter")
}
retainedBool, ok := retained.(bool)
if !ok {
return nil, errors.New("mqtt.message.create retained must be a boolean")
retainedBool, err := params.GetBool("retained")
if err != nil {
return nil, fmt.Errorf("mqtt.message.create retained error: %w", err)
}
//TODO(jwetzell): convert payload into []byte or string for sending
payload, ok := params["payload"]
if !ok {
return nil, errors.New("mqtt.message.create requires a payload parameter")
return nil, errors.New("mqtt.message.create payload error: not found")
}
if payloadBytes, ok := payload.([]byte); ok {
@@ -131,7 +111,7 @@ func init() {
payloadString, ok := payload.(string)
if !ok {
return nil, errors.New("mqtt.message.create payload must be a string or byte array")
return nil, errors.New("mqtt.message.create payload error: not a string or byte array")
}
payloadBytes := []byte(payloadString)

View File

@@ -3,7 +3,7 @@ package processor
import (
"bytes"
"context"
"errors"
"fmt"
"text/template"
"github.com/jwetzell/showbridge-go/internal/config"
@@ -57,16 +57,9 @@ func init() {
Type: "nats.message.create",
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
subject, ok := params["subject"]
if !ok {
return nil, errors.New("nats.message.create requires a subject parameter")
}
subjectString, ok := subject.(string)
if !ok {
return nil, errors.New("nats.message.create subject must be a string")
subjectString, err := params.GetString("subject")
if err != nil {
return nil, fmt.Errorf("nats.message.create subject error: %w", err)
}
subjectTemplate, err := template.New("subject").Parse(subjectString)
@@ -75,16 +68,9 @@ func init() {
return nil, err
}
payload, ok := params["payload"]
if !ok {
return nil, errors.New("nats.message.create requires a payload parameter")
}
payloadString, ok := payload.(string)
if !ok {
return nil, errors.New("nats.message.create payload must be a string")
payloadString, err := params.GetString("payload")
if err != nil {
return nil, fmt.Errorf("nats.message.create payload error: %w", err)
}
payloadTemplate, err := template.New("payload").Parse(payloadString)

View File

@@ -80,16 +80,9 @@ func init() {
Type: "osc.message.create",
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
address, ok := params["address"]
if !ok {
return nil, errors.New("osc.message.create requires an address parameter")
}
addressString, ok := address.(string)
if !ok {
return nil, errors.New("osc.message.create address must be a string")
addressString, err := params.GetString("address")
if err != nil {
return nil, fmt.Errorf("osc.message.create address error: %w", err)
}
addressTemplate, err := template.New("address").Parse(addressString)
@@ -107,16 +100,9 @@ func init() {
return nil, fmt.Errorf("osc.message.create address must be an array found %T", args)
}
types, ok := params["types"]
if !ok {
return nil, errors.New("osc.message.create requires a types parameter with args")
}
typesString, ok := types.(string)
if !ok {
return nil, errors.New("osc.message.create types must be a string")
typesString, err := params.GetString("types")
if err != nil {
return nil, fmt.Errorf("osc.message.create types error: %w", err)
}
if len(rawArgs) != len(typesString) {
@@ -129,7 +115,7 @@ func init() {
argString, ok := rawArg.(string)
if !ok {
return nil, errors.New("osc.message.create arg must be a string")
return nil, errors.New("osc.message.create arg error: not a string")
}
argTemplate, err := template.New("arg").Parse(argString)

View File

@@ -40,16 +40,9 @@ func init() {
Type: "osc.message.filter",
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
address, ok := params["address"]
if !ok {
return nil, errors.New("osc.message.filter requires an address parameter")
}
addressString, ok := address.(string)
if !ok {
return nil, errors.New("osc.message.filter address must be a string")
addressString, err := params.GetString("address")
if err != nil {
return nil, fmt.Errorf("osc.message.filter address error: %w", err)
}
addressPattern := strings.ReplaceAll(addressString, "?", ".")

View File

@@ -2,7 +2,7 @@ package processor
import (
"context"
"errors"
"fmt"
"github.com/expr-lang/expr"
"github.com/expr-lang/expr/vm"
@@ -35,16 +35,9 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
expression, ok := params["expression"]
if !ok {
return nil, errors.New("script.expr requires an expression parameter")
}
expressionString, ok := expression.(string)
if !ok {
return nil, errors.New("script.expr expression must be a string")
expressionString, err := params.GetString("expression")
if err != nil {
return nil, fmt.Errorf("script.expr expression error: %w", err)
}
program, err := expr.Compile(expressionString)

View File

@@ -3,7 +3,7 @@ package processor
import (
"context"
"encoding/json"
"errors"
"fmt"
"github.com/jwetzell/showbridge-go/internal/config"
"modernc.org/quickjs"
@@ -71,16 +71,9 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
program, ok := params["program"]
if !ok {
return nil, errors.New("script.js requires a program parameter")
}
programString, ok := program.(string)
if !ok {
return nil, errors.New("script.js program must be a string")
programString, err := params.GetString("program")
if err != nil {
return nil, fmt.Errorf("script.js program error: %w", err)
}
return &ScriptJS{config: config, Program: programString}, nil

View File

@@ -2,6 +2,7 @@ package processor
import (
"context"
"errors"
"fmt"
extism "github.com/extism/go-sdk"
@@ -44,44 +45,30 @@ func (se *ScriptWASM) Type() string {
func init() {
RegisterProcessor(ProcessorRegistration{
Type: "script.wasm",
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
New: func(processorConfig config.ProcessorConfig) (Processor, error) {
params := processorConfig.Params
path, ok := params["path"]
if !ok {
return nil, fmt.Errorf("script.wasm requires a path parameter")
pathString, err := params.GetString("path")
if err != nil {
return nil, fmt.Errorf("script.wasm path error: %w", err)
}
pathString, ok := path.(string)
if !ok {
return nil, fmt.Errorf("script.wasm path must be a string")
}
functionString := "process"
function, ok := params["function"]
if ok {
specificFunctionString, ok := function.(string)
if !ok {
return nil, fmt.Errorf("script.wasm function must be a string")
functionString, err := params.GetString("function")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
functionString = "process"
} else {
return nil, fmt.Errorf("script.wasm function error: %w", err)
}
functionString = specificFunctionString
}
enableWasiBool := false
enableWasi, ok := params["enableWasi"]
if ok {
specificEnableWasi, ok := enableWasi.(bool)
if !ok {
return nil, fmt.Errorf("script.wasm enableWasi must be a boolean")
enableWasiBool, err := params.GetBool("enableWasi")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
enableWasiBool = false
} else {
return nil, fmt.Errorf("script.wasm enableWasi error: %w", err)
}
enableWasiBool = specificEnableWasi
}
manifest := extism.Manifest{
@@ -100,7 +87,7 @@ func init() {
return nil, err
}
return &ScriptWASM{config: config, Program: program, Function: functionString}, nil
return &ScriptWASM{config: processorConfig, Program: program, Function: functionString}, nil
},
})
}

View File

@@ -3,7 +3,7 @@ package processor
import (
"bytes"
"context"
"errors"
"fmt"
"text/template"
"github.com/jwetzell/showbridge-go/internal/config"
@@ -50,40 +50,19 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
preWait, ok := params["preWait"]
if !ok {
return nil, errors.New("sip.response.audio.create requires a preWait parameter")
preWaitNum, err := params.GetInt("preWait")
if err != nil {
return nil, fmt.Errorf("sip.response.audio.create preWait error: %w", err)
}
preWaitNum, ok := preWait.(float64)
if !ok {
return nil, errors.New("sip.response.audio.create preWait must be a number")
postWaitNum, err := params.GetInt("postWait")
if err != nil {
return nil, fmt.Errorf("sip.response.audio.create postWait error: %w", err)
}
postWait, ok := params["postWait"]
if !ok {
return nil, errors.New("sip.response.audio.create requires a postWait parameter")
}
postWaitNum, ok := postWait.(float64)
if !ok {
return nil, errors.New("sip.response.audio.create postWait must be a number")
}
audioFile, ok := params["audioFile"]
if !ok {
return nil, errors.New("sip.response.audio.create requires a audioFile parameter")
}
audioFileString, ok := audioFile.(string)
if !ok {
return nil, errors.New("sip.response.audio.create audioFile must be a string")
audioFileString, err := params.GetString("audioFile")
if err != nil {
return nil, fmt.Errorf("sip.response.audio.create audioFile error: %w", err)
}
audioFileTemplate, err := template.New("audioFile").Parse(audioFileString)

View File

@@ -4,6 +4,7 @@ import (
"bytes"
"context"
"errors"
"fmt"
"regexp"
"text/template"
@@ -56,40 +57,19 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
preWait, ok := params["preWait"]
if !ok {
return nil, errors.New("sip.response.dtmf.create requires a preWait parameter")
preWaitNum, err := params.GetInt("preWait")
if err != nil {
return nil, fmt.Errorf("sip.response.dtmf.create preWait error: %w", err)
}
preWaitNum, ok := preWait.(float64)
if !ok {
return nil, errors.New("sip.response.dtmf.create preWait must be a number")
postWaitNum, err := params.GetInt("postWait")
if err != nil {
return nil, fmt.Errorf("sip.response.dtmf.create postWait error: %w", err)
}
postWait, ok := params["postWait"]
if !ok {
return nil, errors.New("sip.response.dtmf.create requires a postWait parameter")
}
postWaitNum, ok := postWait.(float64)
if !ok {
return nil, errors.New("sip.response.dtmf.create postWait must be a number")
}
digits, ok := params["digits"]
if !ok {
return nil, errors.New("sip.response.dtmf.create requires a digits parameter")
}
digitsString, ok := digits.(string)
if !ok {
return nil, errors.New("sip.response.dtmf.create digits must be a string")
digitsString, err := params.GetString("digits")
if err != nil {
return nil, fmt.Errorf("sip.response.dtmf.create digits error: %w", err)
}
digitsTemplate, err := template.New("digits").Parse(digitsString)

View File

@@ -3,7 +3,7 @@ package processor
import (
"bytes"
"context"
"errors"
"fmt"
"text/template"
"github.com/jwetzell/showbridge-go/internal/config"
@@ -36,16 +36,9 @@ func init() {
Type: "string.create",
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
tmpl, ok := params["template"]
if !ok {
return nil, errors.New("string.create requires a template parameter")
}
templateString, ok := tmpl.(string)
if !ok {
return nil, errors.New("string.create template must be a string")
templateString, err := params.GetString("template")
if err != nil {
return nil, fmt.Errorf("string.create template error: %w", err)
}
templateTemplate, err := template.New("template").Parse(templateString)

View File

@@ -3,6 +3,7 @@ package processor
import (
"context"
"errors"
"fmt"
"regexp"
"github.com/jwetzell/showbridge-go/internal/config"
@@ -37,16 +38,9 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
pattern, ok := params["pattern"]
if !ok {
return nil, errors.New("string.filter requires a pattern parameter")
}
patternString, ok := pattern.(string)
if !ok {
return nil, errors.New("string.filter pattern must be a string")
patternString, err := params.GetString("pattern")
if err != nil {
return nil, fmt.Errorf("string.filter pattern error: %w", err)
}
patternRegexp, err := regexp.Compile(patternString)

View File

@@ -3,6 +3,7 @@ package processor
import (
"context"
"errors"
"fmt"
"strings"
"github.com/jwetzell/showbridge-go/internal/config"
@@ -35,16 +36,9 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
separator, ok := params["separator"]
if !ok {
return nil, errors.New("string.split requires a separator")
}
separatorString, ok := separator.(string)
if !ok {
return nil, errors.New("string.split separator must be a string")
separatorString, err := params.GetString("separator")
if err != nil {
return nil, fmt.Errorf("string.split separator error: %w", err)
}
return &StringSplit{config: config, Separator: separatorString}, nil

View File

@@ -199,7 +199,7 @@ func TestBadArtnetPacketFilter(t *testing.T) {
Type: 0,
},
params: map[string]any{},
errorString: "artnet.packet.filter requires an opCode parameter",
errorString: "artnet.packet.filter opCode error: not found",
},
{
name: "opCode not a number",
@@ -217,7 +217,7 @@ func TestBadArtnetPacketFilter(t *testing.T) {
Type: 0,
},
params: map[string]any{"opCode": "100"},
errorString: "artnet.packet.filter opCode must be a number",
errorString: "artnet.packet.filter opCode error: not a number",
},
}

View File

@@ -133,25 +133,25 @@ func TestBadIntRandom(t *testing.T) {
name: "no min param",
payload: "hello",
params: map[string]any{"max": 10.0},
errorString: "int.random requires a min parameter",
errorString: "int.random min error: not found",
},
{
name: "no max param",
payload: "hello",
params: map[string]any{"min": 1.0},
errorString: "int.random requires a max parameter",
errorString: "int.random max error: not found",
},
{
name: "min param not a number",
payload: "hello",
params: map[string]any{"min": "1", "max": 10.0},
errorString: "int.random min must be a number",
errorString: "int.random min error: not a number",
},
{
name: "max param not a number",
payload: "hello",
params: map[string]any{"min": 1.0, "max": "10"},
errorString: "int.random max must be a number",
errorString: "int.random max error: not a number",
},
{
name: "max less than min",

View File

@@ -104,7 +104,7 @@ func TestBadMIDIMessageFilter(t *testing.T) {
name: "no type param",
params: map[string]any{},
payload: midi.NoteOn(1, 60, 127),
errorString: "midi.message.filter requires a type parameter",
errorString: "midi.message.filter type error: not found",
},
{
name: "non-string type param",
@@ -112,7 +112,7 @@ func TestBadMIDIMessageFilter(t *testing.T) {
"type": 123,
},
payload: "hello",
errorString: "midi.message.filter type must be a string",
errorString: "midi.message.filter type error: not a string",
},
{
name: "non-midi message input",

View File

@@ -185,7 +185,7 @@ func TestBadOSCMessageCreate(t *testing.T) {
name: "no address parameter",
params: map[string]any{},
payload: "test",
errorString: "osc.message.create requires an address parameter",
errorString: "osc.message.create address error: not found",
},
{
name: "non-string address parameter",
@@ -193,7 +193,7 @@ func TestBadOSCMessageCreate(t *testing.T) {
"address": 123,
},
payload: "test",
errorString: "osc.message.create address must be a string",
errorString: "osc.message.create address error: not a string",
},
{
name: "bad address template",
@@ -220,7 +220,7 @@ func TestBadOSCMessageCreate(t *testing.T) {
"args": []interface{}{"arg1"},
},
payload: "test",
errorString: "osc.message.create requires a types parameter with args",
errorString: "osc.message.create types error: not found",
},
{
name: "args and types length mismatch",
@@ -240,7 +240,7 @@ func TestBadOSCMessageCreate(t *testing.T) {
"types": "ss",
},
payload: "test",
errorString: "osc.message.create arg must be a string",
errorString: "osc.message.create arg error: not a string",
},
{
name: "bad arg template",
@@ -260,7 +260,7 @@ func TestBadOSCMessageCreate(t *testing.T) {
"types": 123,
},
payload: "test",
errorString: "osc.message.create types must be a string",
errorString: "osc.message.create types error: not a string",
},
{
name: "invalid type in types parameter",

View File

@@ -108,7 +108,7 @@ func TestBadOSCMessageFilter(t *testing.T) {
name: "no address parameter",
params: map[string]any{},
payload: osc.OSCMessage{Address: "/test"},
errorString: "osc.message.filter requires an address parameter",
errorString: "osc.message.filter address error: not found",
},
{
name: "non-string address parameter",
@@ -116,7 +116,7 @@ func TestBadOSCMessageFilter(t *testing.T) {
"address": 123,
},
payload: osc.OSCMessage{Address: "/test"},
errorString: "osc.message.filter address must be a string",
errorString: "osc.message.filter address error: not a string",
},
{
name: "bad address pattern",

View File

@@ -103,7 +103,7 @@ func TestBadScriptWASM(t *testing.T) {
name: "no path parameter",
params: map[string]any{},
payload: []byte("hello"),
errorString: "script.wasm requires a path parameter",
errorString: "script.wasm path error: not found",
},
{
name: "non-string path parameter",
@@ -111,7 +111,7 @@ func TestBadScriptWASM(t *testing.T) {
"path": 12345,
},
payload: []byte("hello"),
errorString: "script.wasm path must be a string",
errorString: "script.wasm path error: not a string",
},
{
name: "non-string function",
@@ -121,7 +121,7 @@ func TestBadScriptWASM(t *testing.T) {
"function": 12345,
},
payload: []byte("hello"),
errorString: "script.wasm function must be a string",
errorString: "script.wasm function error: not a string",
},
{
name: "non-boolean enableWasi",

View File

@@ -131,7 +131,7 @@ func TestBadStringCreate(t *testing.T) {
name: "no template param",
payload: "hello",
params: map[string]any{},
errorString: "string.create requires a template parameter",
errorString: "string.create template error: not found",
},
{
name: "non string template",
@@ -139,7 +139,7 @@ func TestBadStringCreate(t *testing.T) {
params: map[string]any{
"template": 1,
},
errorString: "string.create template must be a string",
errorString: "string.create template error: not a string",
},
{
name: "invalid template",

View File

@@ -126,7 +126,7 @@ func TestBadStringFilter(t *testing.T) {
name: "no pattern param",
payload: "hello",
params: map[string]any{},
errorString: "string.filter requires a pattern parameter",
errorString: "string.filter pattern error: not found",
},
{
name: "non-string input",
@@ -142,7 +142,7 @@ func TestBadStringFilter(t *testing.T) {
params: map[string]any{
"pattern": 123,
},
errorString: "string.filter pattern must be a string",
errorString: "string.filter pattern error: not a string",
},
{
name: "invalid regex pattern",

View File

@@ -111,13 +111,13 @@ func TestBadStringSplit(t *testing.T) {
name: "missing separator param",
payload: "part1,part2,part3",
params: map[string]any{},
errorString: "string.split requires a separator",
errorString: "string.split separator error: not found",
},
{
name: "non-string separator param",
payload: "part1,part2,part3",
params: map[string]any{"separator": 123},
errorString: "string.split separator must be a string",
errorString: "string.split separator error: not a string",
},
}

View File

@@ -82,7 +82,7 @@ func TestBadTimeSleep(t *testing.T) {
name: "no-duration param",
payload: "hello",
params: map[string]any{},
errorString: "time.sleep requires a duration parameter",
errorString: "time.sleep duration error: not found",
},
{
name: "non-number duration param",
@@ -90,7 +90,7 @@ func TestBadTimeSleep(t *testing.T) {
params: map[string]any{
"duration": "1000",
},
errorString: "time.sleep duration must be a number",
errorString: "time.sleep duration error: not a number",
},
}

View File

@@ -130,25 +130,25 @@ func TestBadUintRandom(t *testing.T) {
name: "no min param",
payload: "hello",
params: map[string]any{"max": 10.0},
errorString: "uint.random requires a min parameter",
errorString: "uint.random min error: not found",
},
{
name: "no max param",
payload: "hello",
params: map[string]any{"min": 1.0},
errorString: "uint.random requires a max parameter",
errorString: "uint.random max error: not found",
},
{
name: "min param not a number",
payload: "hello",
params: map[string]any{"min": "1", "max": 10.0},
errorString: "uint.random min must be a number",
errorString: "uint.random min error: not a number",
},
{
name: "max param not a number",
payload: "hello",
params: map[string]any{"min": 1.0, "max": "10"},
errorString: "uint.random max must be a number",
errorString: "uint.random max error: not a number",
},
{
name: "max less than min",

View File

@@ -2,7 +2,7 @@ package processor
import (
"context"
"errors"
"fmt"
"time"
"github.com/jwetzell/showbridge-go/internal/config"
@@ -28,15 +28,9 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
duration, ok := params["duration"]
if !ok {
return nil, errors.New("time.sleep requires a duration parameter")
}
durationNum, ok := duration.(float64)
if !ok {
return nil, errors.New("time.sleep duration must be a number")
durationNum, err := params.GetInt("duration")
if err != nil {
return nil, fmt.Errorf("time.sleep duration error: %w", err)
}
return &MetaDelay{config: config, Duration: time.Millisecond * time.Duration(durationNum)}, nil

View File

@@ -3,6 +3,7 @@ package processor
import (
"context"
"errors"
"fmt"
"strconv"
"github.com/jwetzell/showbridge-go/internal/config"
@@ -35,32 +36,26 @@ func (up *UintParse) Type() string {
func init() {
RegisterProcessor(ProcessorRegistration{
Type: "uint.parse",
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
baseNum := 10
base, ok := params["base"]
if ok {
baseFloat, ok := base.(float64)
if !ok {
return nil, errors.New("uint.parse base must be a number")
New: func(moduleConfig config.ProcessorConfig) (Processor, error) {
params := moduleConfig.Params
baseNum, err := params.GetInt("base")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
baseNum = 10
} else {
return nil, fmt.Errorf("uint.parse base error: %w", err)
}
baseNum = int(baseFloat)
}
bitSizeNum := 64
bitSize, ok := params["bitSize"]
if ok {
bitSizeFloat, ok := bitSize.(float64)
if !ok {
return nil, errors.New("uint.parse bitSize must be a number")
bitSizeNum, err := params.GetInt("bitSize")
if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
bitSizeNum = 64
} else {
return nil, fmt.Errorf("uint.parse bitSize error: %w", err)
}
bitSizeNum = int(bitSizeFloat)
}
return &UintParse{config: config, Base: baseNum, BitSize: bitSizeNum}, nil
return &UintParse{config: moduleConfig, Base: baseNum, BitSize: bitSizeNum}, nil
},
})
}

View File

@@ -3,6 +3,7 @@ package processor
import (
"context"
"errors"
"fmt"
"math/rand/v2"
"github.com/jwetzell/showbridge-go/internal/config"
@@ -29,33 +30,21 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params
min, ok := params["min"]
if !ok {
return nil, errors.New("uint.random requires a min parameter")
minInt, err := params.GetInt("min")
if err != nil {
return nil, fmt.Errorf("uint.random min error: %w", err)
}
minFloat, ok := min.(float64)
if !ok {
return nil, errors.New("uint.random min must be a number")
maxInt, err := params.GetInt("max")
if err != nil {
return nil, fmt.Errorf("uint.random max error: %w", err)
}
max, ok := params["max"]
if !ok {
return nil, errors.New("uint.random requires a max parameter")
}
maxFloat, ok := max.(float64)
if !ok {
return nil, errors.New("uint.random max must be a number")
}
if maxFloat < minFloat {
if maxInt < minInt {
return nil, errors.New("uint.random max must be greater than min")
}
return &UintRandom{config: config, Min: uint(minFloat), Max: uint(maxFloat)}, nil
return &UintRandom{config: config, Min: uint(minInt), Max: uint(maxInt)}, nil
},
})
}