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 package config
import (
"errors"
)
type Config struct { type Config struct {
Modules []ModuleConfig `json:"modules"` Modules []ModuleConfig `json:"modules"`
Routes []RouteConfig `json:"routes"` 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 { type ModuleConfig struct {
Id string `json:"id"` Id string `json:"id"`
Type string `json:"type"` Type string `json:"type"`
Params map[string]any `json:"params"` Params Params `json:"params"`
} }
type RouteConfig struct { type RouteConfig struct {
@@ -19,5 +74,5 @@ type RouteConfig struct {
type ProcessorConfig struct { type ProcessorConfig struct {
Type string `json:"type"` Type string `json:"type"`
Params map[string]any `json:"params"` Params Params `json:"params"`
} }

View File

@@ -57,17 +57,10 @@ func init() {
Type: "http.server", Type: "http.server",
New: func(config config.ModuleConfig) (Module, error) { New: func(config config.ModuleConfig) (Module, error) {
params := config.Params params := config.Params
port, ok := params["port"] portNum, err := params.GetInt("port")
if !ok { if err != nil {
return nil, errors.New("http.server requires a port parameter") 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 return &HTTPServer{Port: uint16(portNum), config: config, logger: CreateLogger(config)}, nil
}, },
}) })

View File

@@ -29,16 +29,9 @@ func init() {
Type: "midi.input", Type: "midi.input",
New: func(config config.ModuleConfig) (Module, error) { New: func(config config.ModuleConfig) (Module, error) {
params := config.Params params := config.Params
port, ok := params["port"] portString, err := params.GetString("port")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.input port error: %w", err)
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")
} }
return &MIDIInput{config: config, Port: portString, logger: CreateLogger(config)}, nil 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) { New: func(config config.ModuleConfig) (Module, error) {
params := config.Params params := config.Params
port, ok := params["port"] portString, err := params.GetString("port")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.output port error: %w", err)
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")
} }
return &MIDIOutput{config: config, Port: portString, logger: CreateLogger(config)}, nil return &MIDIOutput{config: config, Port: portString, logger: CreateLogger(config)}, nil

View File

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

View File

@@ -27,42 +27,31 @@ type NATSServer struct {
func init() { func init() {
RegisterModule(ModuleRegistration{ RegisterModule(ModuleRegistration{
Type: "nats.server", Type: "nats.server",
New: func(config config.ModuleConfig) (Module, error) { New: func(moduleConfig config.ModuleConfig) (Module, error) {
params := config.Params params := moduleConfig.Params
portNum := 4222 portNum, err := params.GetInt("port")
if err != nil {
port, ok := params["port"] if errors.Is(err, config.ErrParamNotFound) {
if ok { portNum = 4222
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)
} else { } else {
portNum = int(specificportNum) return nil, fmt.Errorf("nats.server port error: %w", err)
} }
} }
ipString := "0.0.0.0" ipString, err := params.GetString("ip")
if err != nil {
ip, ok := params["ip"] if errors.Is(err, config.ErrParamNotFound) {
if ok { ipString = "0.0.0.0"
} else {
specificIpString, ok := ip.(string) return nil, fmt.Errorf("nats.server ip error: %w", err)
if !ok {
return nil, errors.New("nats.server ip must be a string")
} }
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 { if err != nil {
return nil, err 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", Type: "serial.client",
New: func(config config.ModuleConfig) (Module, error) { New: func(config config.ModuleConfig) (Module, error) {
params := config.Params params := config.Params
port, ok := params["port"] portString, err := params.GetString("port")
if err != nil {
if !ok { return nil, fmt.Errorf("serial.client port error: %w", err)
return nil, errors.New("serial.client requires a port parameter")
} }
portString, ok := port.(string) framingMethodString, err := params.GetString("framing")
if err != nil {
if !ok { return nil, fmt.Errorf("serial.client framing error: %w", err)
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")
} }
framer := framer.GetFramer(framingMethodString) framer := framer.GetFramer(framingMethodString)
if framer == nil { 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"] baudRateInt, err := params.GetInt("baudRate")
if !ok { if err != nil {
return nil, errors.New("serial.client requires a baudRate parameter") return nil, fmt.Errorf("serial.client baudRate error: %w", err)
}
baudRateNum, ok := buadRate.(float64)
if !ok {
return nil, errors.New("serial.client baudRate must be a number")
} }
mode := serial.Mode{ mode := serial.Mode{
BaudRate: int(baudRateNum), BaudRate: baudRateInt,
} }
return &SerialClient{config: config, Port: portString, Framer: framer, Mode: &mode, logger: CreateLogger(config)}, nil 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() { func init() {
RegisterModule(ModuleRegistration{ RegisterModule(ModuleRegistration{
Type: "sip.call.server", Type: "sip.call.server",
New: func(config config.ModuleConfig) (Module, error) { New: func(moduleConfig config.ModuleConfig) (Module, error) {
params := config.Params params := moduleConfig.Params
portNum := 5060 portNum, err := params.GetInt("port")
if err != nil {
port, ok := params["port"] if errors.Is(err, config.ErrParamNotFound) {
if ok { portNum = 5060
specificPortNum, ok := port.(float64) } else {
return nil, fmt.Errorf("sip.call.server port error: %w", err)
if !ok {
return nil, errors.New("sip.call.server port must be a number")
} }
portNum = int(specificPortNum)
} }
ipString := "0.0.0.0" ipString, err := params.GetString("ip")
if err != nil {
ip, ok := params["ip"] if errors.Is(err, config.ErrParamNotFound) {
if ok { ipString = "0.0.0.0"
} else {
specificIpString, ok := ip.(string) return nil, fmt.Errorf("sip.call.server ip error: %w", err)
if !ok {
return nil, errors.New("sip.call.server ip must be a string")
} }
ipString = specificIpString
} }
transportString := "udp" transportString, err := params.GetString("transport")
if err != nil {
transport, ok := params["transport"] if errors.Is(err, config.ErrParamNotFound) {
if ok { transportString = "udp"
} else {
specificTransportString, ok := transport.(string) return nil, fmt.Errorf("sip.call.server transport error: %w", err)
if !ok {
return nil, errors.New("sip.call.server transport must be a string")
} }
transportString = specificTransportString
} }
userAgentString := "showbridge" userAgentString, err := params.GetString("userAgent")
if err != nil {
userAgent, ok := params["userAgent"] if errors.Is(err, config.ErrParamNotFound) {
if ok { userAgentString = "showbridge"
} else {
specificUserAgentString, ok := userAgent.(string) return nil, fmt.Errorf("sip.call.server userAgent error: %w", err)
if !ok {
return nil, errors.New("sip.call.server userAgent must be a string")
} }
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() { func init() {
RegisterModule(ModuleRegistration{ RegisterModule(ModuleRegistration{
Type: "sip.dtmf.server", Type: "sip.dtmf.server",
New: func(config config.ModuleConfig) (Module, error) { New: func(moduleConfig config.ModuleConfig) (Module, error) {
params := config.Params params := moduleConfig.Params
portNum := 5060
port, ok := params["port"] portNum, err := params.GetInt("port")
if ok { if err != nil {
specificPortNum, ok := port.(float64)
if !ok { if errors.Is(err, config.ErrParamNotFound) {
return nil, errors.New("sip.dtmf.server port must be a number") portNum = 5060
} else {
return nil, fmt.Errorf("sip.dtmf.server port error: %w", err)
} }
portNum = int(specificPortNum)
} }
ipString := "0.0.0.0" ipString, err := params.GetString("ip")
if err != nil {
ip, ok := params["ip"] if errors.Is(err, config.ErrParamNotFound) {
if ok { ipString = "0.0.0.0"
} else {
specificIpString, ok := ip.(string) return nil, fmt.Errorf("sip.dtmf.server ip error: %w", err)
if !ok {
return nil, errors.New("sip.dtmf.server ip must be a string")
} }
ipString = specificIpString
} }
transportString := "udp" transportString, err := params.GetString("transport")
if err != nil {
transport, ok := params["transport"] if errors.Is(err, config.ErrParamNotFound) {
if ok { transportString = "udp"
} else {
specificTransportString, ok := transport.(string) return nil, fmt.Errorf("sip.dtmf.server transport error: %w", err)
if !ok {
return nil, errors.New("sip.dtmf.server transport must be a string")
} }
transportString = specificTransportString
} }
userAgentString := "showbridge" userAgentString, err := params.GetString("userAgent")
if err != nil {
userAgent, ok := params["userAgent"] if errors.Is(err, config.ErrParamNotFound) {
if ok { userAgentString = "showbridge"
} else {
specificUserAgentString, ok := userAgent.(string) return nil, fmt.Errorf("sip.dtmf.server userAgent error: %w", err)
if !ok {
return nil, errors.New("sip.dtmf.server userAgent must be a string")
} }
userAgentString = specificUserAgentString
} }
separator, ok := params["separator"] separatorString, err := params.GetString("separator")
if !ok { if err != nil {
return nil, errors.New("sip.dtmf.server requires a separator parameter") return nil, fmt.Errorf("sip.dtmf.server separator error: %w", err)
}
separatorString, ok := separator.(string)
if !ok {
return nil, errors.New("sip.dtmf.server separator must be a string")
} }
if len(separatorString) != 1 { if len(separatorString) != 1 {
@@ -115,7 +98,7 @@ func init() {
if !strings.ContainsRune("0123456789*#ABCD", rune(separatorString[0])) { if !strings.ContainsRune("0123456789*#ABCD", rune(separatorString[0])) {
return nil, errors.New("sip.dtmf.server separator must be a valid DTMF character") 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", Type: "net.tcp.client",
New: func(config config.ModuleConfig) (Module, error) { New: func(config config.ModuleConfig) (Module, error) {
params := config.Params params := config.Params
host, ok := params["host"] hostString, err := params.GetString("host")
if err != nil {
if !ok { return nil, fmt.Errorf("net.tcp.client host error: %w", err)
return nil, errors.New("net.tcp.client requires a host parameter")
} }
hostString, ok := host.(string) portNum, err := params.GetInt("port")
if err != nil {
if !ok { return nil, fmt.Errorf("net.tcp.client port error: %w", err)
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")
} }
addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", hostString, uint16(portNum))) addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", hostString, uint16(portNum)))
@@ -57,22 +44,15 @@ func init() {
return nil, err return nil, err
} }
framingMethod, ok := params["framing"] framingMethodString, err := params.GetString("framing")
if err != nil {
if !ok { return nil, fmt.Errorf("net.tcp.client framing error: %w", err)
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")
} }
framer := framer.GetFramer(framingMethodString) framer := framer.GetFramer(framingMethodString)
if framer == nil { 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 return &TCPClient{framer: framer, Addr: addr, config: config, logger: CreateLogger(config)}, nil
}, },

View File

@@ -33,55 +33,38 @@ type TCPServer struct {
func init() { func init() {
RegisterModule(ModuleRegistration{ RegisterModule(ModuleRegistration{
Type: "net.tcp.server", Type: "net.tcp.server",
New: func(config config.ModuleConfig) (Module, error) { New: func(moduleConfig config.ModuleConfig) (Module, error) {
params := config.Params params := moduleConfig.Params
port, ok := params["port"] portNum, err := params.GetInt("port")
if !ok { if err != nil {
return nil, errors.New("net.tcp.server requires a port parameter") return nil, fmt.Errorf("net.tcp.server port error: %w", err)
} }
portNum, ok := port.(float64) framingMethodString, err := params.GetString("framing")
if err != nil {
if !ok { return nil, fmt.Errorf("net.tcp.server framing error: %w", err)
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")
} }
framer := framer.GetFramer(framingMethodString) framer := framer.GetFramer(framingMethodString)
if framer == nil { 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" ipString, err := params.GetString("ip")
if err != nil {
ip, ok := params["ip"] if errors.Is(err, config.ErrParamNotFound) {
if ok { ipString = "0.0.0.0"
} else {
specificIpString, ok := ip.(string) return nil, fmt.Errorf("net.tcp.server ip error: %w", err)
if !ok {
return nil, errors.New("net.tcp.server ip must be a string")
} }
ipString = specificIpString
} }
addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ipString, uint16(portNum))) addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ipString, uint16(portNum)))
if err != nil { if err != nil {
return nil, err 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", name: "no port param",
params: map[string]any{}, params: map[string]any{},
errorString: "http.server requires a port parameter", errorString: "http.server port error: not found",
}, },
{ {
name: "non-numeric port", name: "non-numeric port",
params: map[string]any{"port": "3000"}, 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", name: "no port param",
params: map[string]any{}, params: map[string]any{},
errorString: "midi.input requires a port parameter", errorString: "midi.input port error: not found",
}, },
{ {
name: "non-string port", name: "non-string port",
params: map[string]any{"port": 123}, 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", name: "no port param",
params: map[string]any{}, params: map[string]any{},
errorString: "midi.output requires a port parameter", errorString: "midi.output port error: not found",
}, },
{ {
name: "non-string port", name: "non-string port",
params: map[string]any{"port": 123}, 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", "topic": "test/topic",
"clientId": "test", "clientId": "test",
}, },
errorString: "mqtt.client requires a broker parameter", errorString: "mqtt.client broker error: not found",
}, },
{ {
name: "non-string broker", name: "non-string broker",
@@ -57,7 +57,7 @@ func TestBadMQTTClient(t *testing.T) {
"topic": "test/topic", "topic": "test/topic",
"clientId": "test", "clientId": "test",
}, },
errorString: "mqtt.client broker must be a string", errorString: "mqtt.client broker error: not a string",
}, },
{ {
name: "no topic param", name: "no topic param",
@@ -65,7 +65,7 @@ func TestBadMQTTClient(t *testing.T) {
"broker": "mqtt://localhost:1883", "broker": "mqtt://localhost:1883",
"clientId": "test", "clientId": "test",
}, },
errorString: "mqtt.client requires a topic parameter", errorString: "mqtt.client topic error: not found",
}, },
{ {
name: "non-string topic", name: "non-string topic",
@@ -74,7 +74,7 @@ func TestBadMQTTClient(t *testing.T) {
"topic": 123, "topic": 123,
"clientId": "test", "clientId": "test",
}, },
errorString: "mqtt.client topic must be a string", errorString: "mqtt.client topic error: not a string",
}, },
{ {
name: "no clientId param", name: "no clientId param",
@@ -82,7 +82,7 @@ func TestBadMQTTClient(t *testing.T) {
"broker": "mqtt://localhost:1883", "broker": "mqtt://localhost:1883",
"topic": "test/topic", "topic": "test/topic",
}, },
errorString: "mqtt.client requires a clientId parameter", errorString: "mqtt.client clientId error: not found",
}, },
{ {
name: "non-string clientId", name: "non-string clientId",
@@ -91,7 +91,7 @@ func TestBadMQTTClient(t *testing.T) {
"topic": "test/topic", "topic": "test/topic",
"clientId": 123, "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{ params: map[string]any{
"subject": "test/subject", "subject": "test/subject",
}, },
errorString: "nats.client requires a url parameter", errorString: "nats.client url error: not found",
}, },
{ {
name: "non-string url", name: "non-string url",
@@ -54,14 +54,14 @@ func TestBadNATSClient(t *testing.T) {
"url": 123, "url": 123,
"subject": "test/subject", "subject": "test/subject",
}, },
errorString: "nats.client url must be a string", errorString: "nats.client url error: not a string",
}, },
{ {
name: "no subject param", name: "no subject param",
params: map[string]any{ params: map[string]any{
"url": "nats://127.0.0.1:4222", "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", name: "non-string subject",
@@ -69,7 +69,7 @@ func TestBadNATSClient(t *testing.T) {
"url": "nats://127.0.0.1:4222", "url": "nats://127.0.0.1:4222",
"subject": 123, "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{ params: map[string]any{
"ip": 123, "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{ params: map[string]any{
"framing": "LF", "framing": "LF",
}, },
errorString: "serial.client requires a port parameter", errorString: "serial.client port error: not found",
}, },
{ {
name: "non-string port param", name: "non-string port param",
@@ -55,14 +55,14 @@ func TestBadSerialClient(t *testing.T) {
"port": 8000, "port": 8000,
"framing": "LF", "framing": "LF",
}, },
errorString: "serial.client port must be a string", errorString: "serial.client port error: not a string",
}, },
{ {
name: "no framing param", name: "no framing param",
params: map[string]any{ params: map[string]any{
"port": "/dev/ttyUSB0", "port": "/dev/ttyUSB0",
}, },
errorString: "serial.client requires a framing parameter", errorString: "serial.client framing error: not found",
}, },
{ {
name: "non-string framing param", name: "non-string framing param",
@@ -70,7 +70,7 @@ func TestBadSerialClient(t *testing.T) {
"port": "/dev/ttyUSB0", "port": "/dev/ttyUSB0",
"framing": 1, "framing": 1,
}, },
errorString: "serial.client framing method must be a string", errorString: "serial.client framing error: not a string",
}, },
{ {
name: "unkown framing method", name: "unkown framing method",

View File

@@ -42,28 +42,28 @@ func TestBadSIPCallServer(t *testing.T) {
params: map[string]any{ params: map[string]any{
"port": "8000", "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", name: "non-string ip param",
params: map[string]any{ params: map[string]any{
"ip": 123, "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", name: "non-string transport param",
params: map[string]any{ params: map[string]any{
"transport": 123, "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", name: "non-string userAgent param",
params: map[string]any{ params: map[string]any{
"userAgent": 123, "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", name: "no separator param",
params: map[string]any{}, 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", name: "non-string separator param",
params: map[string]any{ params: map[string]any{
"separator": 123, "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", name: "non-number port param",
@@ -58,7 +58,7 @@ func TestBadSIPDTMFServer(t *testing.T) {
"separator": "#", "separator": "#",
"port": "8000", "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", name: "non-string ip param",
@@ -66,7 +66,7 @@ func TestBadSIPDTMFServer(t *testing.T) {
"separator": "#", "separator": "#",
"ip": 123, "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", name: "non-string transport param",
@@ -74,7 +74,7 @@ func TestBadSIPDTMFServer(t *testing.T) {
"separator": "#", "separator": "#",
"transport": 123, "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", name: "non-string userAgent param",
@@ -82,7 +82,7 @@ func TestBadSIPDTMFServer(t *testing.T) {
"separator": "#", "separator": "#",
"userAgent": 123, "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{ params: map[string]any{
"host": "localhost", "host": "localhost",
}, },
errorString: "net.tcp.client requires a port parameter", errorString: "net.tcp.client port error: not found",
}, },
{ {
name: "non-number port param", name: "non-number port param",
@@ -55,14 +55,14 @@ func TestBadTCPClient(t *testing.T) {
"host": "localhost", "host": "localhost",
"port": "8000", "port": "8000",
}, },
errorString: "net.tcp.client port must be a number", errorString: "net.tcp.client port error: not a number",
}, },
{ {
name: "no host param", name: "no host param",
params: map[string]any{ params: map[string]any{
"port": 8000.0, "port": 8000.0,
}, },
errorString: "net.tcp.client requires a host parameter", errorString: "net.tcp.client host error: not found",
}, },
{ {
name: "non-string host param", name: "non-string host param",
@@ -70,7 +70,7 @@ func TestBadTCPClient(t *testing.T) {
"host": 123, "host": 123,
"port": 8000.0, "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{ params: map[string]any{
"framing": "LF", "framing": "LF",
}, },
errorString: "net.tcp.server requires a port parameter", errorString: "net.tcp.server port error: not found",
}, },
{ {
name: "non-number port param", name: "non-number port param",
@@ -54,14 +54,14 @@ func TestBadTCPServer(t *testing.T) {
"port": "8000", "port": "8000",
"framing": "LF", "framing": "LF",
}, },
errorString: "net.tcp.server port must be a number", errorString: "net.tcp.server port error: not a number",
}, },
{ {
name: "no framing param", name: "no framing param",
params: map[string]any{ params: map[string]any{
"port": 8000.0, "port": 8000.0,
}, },
errorString: "net.tcp.server requires a framing parameter", errorString: "net.tcp.server framing error: not found",
}, },
{ {
name: "non-string framing param", name: "non-string framing param",
@@ -69,7 +69,7 @@ func TestBadTCPServer(t *testing.T) {
"port": 8000.0, "port": 8000.0,
"framing": 1, "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", name: "unkown framing method",
@@ -86,7 +86,7 @@ func TestBadTCPServer(t *testing.T) {
"framing": "LF", "framing": "LF",
"ip": 123, "ip": 123,
}, },
errorString: "net.tcp.server ip must be a string", errorString: "net.tcp.server ip error: not a string",
}, },
{ {
name: "invalid addr", name: "invalid addr",

View File

@@ -43,14 +43,14 @@ func TestBadTimeInterval(t *testing.T) {
{ {
name: "no duration param", name: "no duration param",
params: map[string]any{}, params: map[string]any{},
errorString: "time.interval requires a duration parameter", errorString: "time.interval duration error: not found",
}, },
{ {
name: "non-number duration param", name: "non-number duration param",
params: map[string]any{ params: map[string]any{
"duration": "8000", "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", name: "no duration param",
params: map[string]any{}, params: map[string]any{},
errorString: "time.timer requires a duration parameter", errorString: "time.timer duration error: not found",
}, },
{ {
name: "non-number duration param", name: "non-number duration param",
params: map[string]any{ params: map[string]any{
"duration": "8000", "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{ params: map[string]any{
"host": "localhost", "host": "localhost",
}, },
errorString: "net.udp.client requires a port parameter", errorString: "net.udp.client port error: not found",
}, },
{ {
name: "non-number port param", name: "non-number port param",
@@ -55,14 +55,14 @@ func TestBadUDPClient(t *testing.T) {
"host": "localhost", "host": "localhost",
"port": "8000", "port": "8000",
}, },
errorString: "net.udp.client port must be a number", errorString: "net.udp.client port error: not a number",
}, },
{ {
name: "no host param", name: "no host param",
params: map[string]any{ params: map[string]any{
"port": 8000.0, "port": 8000.0,
}, },
errorString: "net.udp.client requires a host parameter", errorString: "net.udp.client host error: not found",
}, },
{ {
name: "non-string host param", name: "non-string host param",
@@ -70,7 +70,7 @@ func TestBadUDPClient(t *testing.T) {
"host": 123, "host": 123,
"port": 8000.0, "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{ params: map[string]any{
"ip": "localhost", "ip": "localhost",
}, },
errorString: "net.udp.multicast requires a port parameter", errorString: "net.udp.multicast port error: not found",
}, },
{ {
name: "non-number port param", name: "non-number port param",
@@ -54,14 +54,14 @@ func TestBadUDPMulticast(t *testing.T) {
"ip": "localhost", "ip": "localhost",
"port": "8000", "port": "8000",
}, },
errorString: "net.udp.multicast port must be a number", errorString: "net.udp.multicast port error: not a number",
}, },
{ {
name: "no ip param", name: "no ip param",
params: map[string]any{ params: map[string]any{
"port": 8000.0, "port": 8000.0,
}, },
errorString: "net.udp.multicast requires an ip parameter", errorString: "net.udp.multicast ip error: not found",
}, },
{ {
name: "non-string ip param", name: "non-string ip param",
@@ -69,7 +69,7 @@ func TestBadUDPMulticast(t *testing.T) {
"ip": 123, "ip": 123,
"port": 8000.0, "port": 8000.0,
}, },
errorString: "net.udp.multicast ip must be a string", errorString: "net.udp.multicast ip error: not a string",
}, },
{ {
name: "invalid addr", name: "invalid addr",

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,36 +25,23 @@ type UDPMulticast struct {
func init() { func init() {
RegisterModule(ModuleRegistration{ RegisterModule(ModuleRegistration{
Type: "net.udp.multicast", Type: "net.udp.multicast",
New: func(config config.ModuleConfig) (Module, error) { New: func(moduleConfig config.ModuleConfig) (Module, error) {
params := config.Params params := moduleConfig.Params
ip, ok := params["ip"] ipString, err := params.GetString("ip")
if err != nil {
if !ok { return nil, fmt.Errorf("net.udp.multicast ip error: %w", err)
return nil, errors.New("net.udp.multicast requires an ip parameter")
} }
ipString, ok := ip.(string) portNum, err := params.GetInt("port")
if err != nil {
if !ok { return nil, fmt.Errorf("net.udp.multicast port error: %w", err)
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")
} }
addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", ipString, uint16(portNum))) addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", ipString, uint16(portNum)))
if err != nil { if err != nil {
return nil, err 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() { func init() {
RegisterModule(ModuleRegistration{ RegisterModule(ModuleRegistration{
Type: "net.udp.server", Type: "net.udp.server",
New: func(config config.ModuleConfig) (Module, error) { New: func(moduleConfig config.ModuleConfig) (Module, error) {
params := config.Params params := moduleConfig.Params
port, ok := params["port"] portNum, err := params.GetInt("port")
if !ok { if err != nil {
return nil, errors.New("net.udp.server requires a port parameter") return nil, fmt.Errorf("net.udp.server port error: %w", err)
} }
portNum, ok := port.(float64) ipString, err := params.GetString("ip")
if err != nil {
if !ok { if errors.Is(err, config.ErrParamNotFound) {
return nil, errors.New("net.udp.server port must be a number") ipString = "0.0.0.0"
} else {
return nil, fmt.Errorf("net.udp.server ip error: %w", err)
} }
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 = specificIpString
} }
addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", ipString, uint16(portNum))) addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", ipString, uint16(portNum)))
@@ -56,18 +46,15 @@ func init() {
return nil, err return nil, err
} }
bufferSizeNum := 2048 bufferSizeNum, err := params.GetInt("bufferSize")
bufferSize, ok := params["bufferSize"] if err != nil {
if errors.Is(err, config.ErrParamNotFound) {
if ok { bufferSizeNum = 2048
bufferSizeFloat, ok := bufferSize.(float64) } else {
return nil, fmt.Errorf("net.udp.server bufferSize error: %w", err)
if !ok {
return nil, errors.New("net.udp.server bufferSize must be a number")
} }
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) { New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params params := config.Params
opCode, ok := params["opCode"] opCodeNum, err := params.GetInt("opCode")
if !ok { if err != nil {
return nil, fmt.Errorf("artnet.packet.filter requires an opCode parameter") return nil, fmt.Errorf("artnet.packet.filter opCode error: %w", err)
}
opCodeNum, ok := opCode.(float64)
if !ok {
return nil, fmt.Errorf("artnet.packet.filter opCode must be a number")
} }
return &ArtNetPacketFilter{config: config, OpCode: uint16(opCodeNum)}, nil return &ArtNetPacketFilter{config: config, OpCode: uint16(opCodeNum)}, nil

View File

@@ -3,6 +3,7 @@ package processor
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"strconv" "strconv"
"github.com/jwetzell/showbridge-go/internal/config" "github.com/jwetzell/showbridge-go/internal/config"
@@ -34,20 +35,18 @@ func (fp *FloatParse) Type() string {
func init() { func init() {
RegisterProcessor(ProcessorRegistration{ RegisterProcessor(ProcessorRegistration{
Type: "float.parse", Type: "float.parse",
New: func(config config.ProcessorConfig) (Processor, error) { New: func(moduleConfig config.ProcessorConfig) (Processor, error) {
params := config.Params params := moduleConfig.Params
bitSizeNum := 64
bitSize, ok := params["bitSize"]
if ok {
bitSizeFloat, ok := bitSize.(float64)
if !ok { bitSizeNum, err := params.GetInt("bitSize")
return nil, errors.New("float.parse bitSize must be a number") 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 ( import (
"bytes" "bytes"
"context" "context"
"errors" "fmt"
"strconv" "strconv"
"text/template" "text/template"
@@ -187,16 +187,9 @@ func init() {
// TODO(jwetzell): make some params optional // TODO(jwetzell): make some params optional
params := config.Params params := config.Params
id, ok := params["id"] idString, err := params.GetString("id")
if err != nil {
if !ok { return nil, fmt.Errorf("freed.create id error: %w", err)
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")
} }
idTemplate, err := template.New("id").Parse(idString) idTemplate, err := template.New("id").Parse(idString)
@@ -205,44 +198,23 @@ func init() {
return nil, err return nil, err
} }
pan, ok := params["pan"] panString, err := params.GetString("pan")
if err != nil {
if !ok { return nil, fmt.Errorf("freed.create pan error: %w", err)
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")
} }
panTemplate, err := template.New("pan").Parse(panString) panTemplate, err := template.New("pan").Parse(panString)
tilt, ok := params["tilt"] tiltString, err := params.GetString("tilt")
if err != nil {
if !ok { return nil, fmt.Errorf("freed.create tilt error: %w", err)
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")
} }
tiltTemplate, err := template.New("tilt").Parse(tiltString) tiltTemplate, err := template.New("tilt").Parse(tiltString)
roll, ok := params["roll"] rollString, err := params.GetString("roll")
if err != nil {
if !ok { return nil, fmt.Errorf("freed.create roll error: %w", err)
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")
} }
rollTemplate, err := template.New("roll").Parse(rollString) rollTemplate, err := template.New("roll").Parse(rollString)
@@ -251,16 +223,9 @@ func init() {
return nil, err return nil, err
} }
posX, ok := params["posX"] posXString, err := params.GetString("posX")
if err != nil {
if !ok { return nil, fmt.Errorf("freed.create posX error: %w", err)
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")
} }
posXTemplate, err := template.New("posX").Parse(posXString) posXTemplate, err := template.New("posX").Parse(posXString)
@@ -269,16 +234,9 @@ func init() {
return nil, err return nil, err
} }
posY, ok := params["posY"] posYString, err := params.GetString("posY")
if err != nil {
if !ok { return nil, fmt.Errorf("freed.create posY error: %w", err)
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")
} }
posYTemplate, err := template.New("posY").Parse(posYString) posYTemplate, err := template.New("posY").Parse(posYString)
@@ -287,16 +245,9 @@ func init() {
return nil, err return nil, err
} }
posZ, ok := params["posZ"] posZString, err := params.GetString("posZ")
if err != nil {
if !ok { return nil, fmt.Errorf("freed.create posZ error: %w", err)
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")
} }
posZTemplate, err := template.New("posZ").Parse(posZString) posZTemplate, err := template.New("posZ").Parse(posZString)
@@ -305,30 +256,16 @@ func init() {
return nil, err return nil, err
} }
zoom, ok := params["zoom"] zoomString, err := params.GetString("zoom")
if err != nil {
if !ok { return nil, fmt.Errorf("freed.create zoom error: %w", err)
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")
} }
zoomTemplate, err := template.New("zoom").Parse(zoomString) zoomTemplate, err := template.New("zoom").Parse(zoomString)
focus, ok := params["focus"] focusString, err := params.GetString("focus")
if err != nil {
if !ok { return nil, fmt.Errorf("freed.create focus error: %w", err)
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")
} }
focusTemplate, err := template.New("focus").Parse(focusString) focusTemplate, err := template.New("focus").Parse(focusString)

View File

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

View File

@@ -44,18 +44,11 @@ func (hrf *HTTPRequestFilter) Type() string {
func init() { func init() {
RegisterProcessor(ProcessorRegistration{ RegisterProcessor(ProcessorRegistration{
Type: "http.request.filter", Type: "http.request.filter",
New: func(config config.ProcessorConfig) (Processor, error) { New: func(moduleConfig config.ProcessorConfig) (Processor, error) {
params := config.Params params := moduleConfig.Params
path, ok := params["path"] pathString, err := params.GetString("path")
if err != nil {
if !ok { return nil, fmt.Errorf("http.request.filter path error: %w", err)
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")
} }
pathRegexp, err := regexp.Compile(fmt.Sprintf("^%s$", pathString)) pathRegexp, err := regexp.Compile(fmt.Sprintf("^%s$", pathString))
@@ -64,18 +57,17 @@ func init() {
return nil, err return nil, err
} }
method, ok := params["method"] methodString, err := params.GetString("method")
if err != nil {
if ok { if errors.Is(err, config.ErrParamNotFound) {
methodString, ok := method.(string) return &HTTPRequestFilter{config: moduleConfig, Path: pathRegexp}, nil
} else {
if !ok { return nil, fmt.Errorf("http.request.filter method error: %w", err)
return nil, errors.New("http.request.filter method must be a string")
} }
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 ( import (
"bytes" "bytes"
"context" "context"
"errors" "fmt"
"text/template" "text/template"
"github.com/jwetzell/showbridge-go/internal/config" "github.com/jwetzell/showbridge-go/internal/config"
@@ -44,28 +44,14 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) { New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params params := config.Params
status, ok := params["status"] statusNum, err := params.GetInt("status")
if err != nil {
if !ok { return nil, fmt.Errorf("http.response.create status error: %w", err)
return nil, errors.New("http.response.create requires a status parameter")
} }
statusNum, ok := status.(float64) bodyTemplateString, err := params.GetString("bodyTemplate")
if err != nil {
if !ok { return nil, fmt.Errorf("http.response.create bodyTemplate error: %w", err)
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")
} }
bodyTemplate, err := template.New("body").Parse(bodyTemplateString) bodyTemplate, err := template.New("body").Parse(bodyTemplateString)

View File

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

View File

@@ -3,6 +3,7 @@ package processor
import ( import (
"context" "context"
"errors" "errors"
"fmt"
"math/rand/v2" "math/rand/v2"
"github.com/jwetzell/showbridge-go/internal/config" "github.com/jwetzell/showbridge-go/internal/config"
@@ -29,33 +30,21 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) { New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params params := config.Params
min, ok := params["min"] minInt, err := params.GetInt("min")
if !ok { if err != nil {
return nil, errors.New("int.random requires a min parameter") return nil, fmt.Errorf("int.random min error: %w", err)
} }
minFloat, ok := min.(float64) maxInt, err := params.GetInt("max")
if err != nil {
if !ok { return nil, fmt.Errorf("int.random max error: %w", err)
return nil, errors.New("int.random min must be a number")
} }
max, ok := params["max"] if maxInt < minInt {
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 {
return nil, errors.New("int.random max must be greater than min") 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 ( import (
"bytes" "bytes"
"context" "context"
"errors"
"fmt" "fmt"
"strconv" "strconv"
"text/template" "text/template"
@@ -32,16 +31,9 @@ func newMidiNoteOnCreate(config config.ProcessorConfig) (Processor, error) {
params := config.Params params := config.Params
channel, ok := params["channel"] channelString, err := params.GetString("channel")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.message.create channel error: %w", err)
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")
} }
channelTemplate, err := template.New("channel").Parse(channelString) channelTemplate, err := template.New("channel").Parse(channelString)
@@ -50,16 +42,9 @@ func newMidiNoteOnCreate(config config.ProcessorConfig) (Processor, error) {
return nil, err return nil, err
} }
note, ok := params["note"] noteString, err := params.GetString("note")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.message.create note error: %w", err)
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")
} }
noteTemplate, err := template.New("note").Parse(noteString) noteTemplate, err := template.New("note").Parse(noteString)
@@ -68,16 +53,9 @@ func newMidiNoteOnCreate(config config.ProcessorConfig) (Processor, error) {
return nil, err return nil, err
} }
velocity, ok := params["velocity"] velocityString, err := params.GetString("velocity")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.message.create velocity error: %w", err)
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")
} }
velocityTemplate, err := template.New("velocity").Parse(velocityString) velocityTemplate, err := template.New("velocity").Parse(velocityString)
@@ -123,16 +101,9 @@ func newMidiNoteOffCreate(config config.ProcessorConfig) (Processor, error) {
params := config.Params params := config.Params
channel, ok := params["channel"] channelString, err := params.GetString("channel")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.message.create channel error: %w", err)
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")
} }
channelTemplate, err := template.New("channel").Parse(channelString) channelTemplate, err := template.New("channel").Parse(channelString)
@@ -141,16 +112,9 @@ func newMidiNoteOffCreate(config config.ProcessorConfig) (Processor, error) {
return nil, err return nil, err
} }
note, ok := params["note"] noteString, err := params.GetString("note")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.message.create note error: %w", err)
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")
} }
noteTemplate, err := template.New("note").Parse(noteString) noteTemplate, err := template.New("note").Parse(noteString)
@@ -159,6 +123,17 @@ func newMidiNoteOffCreate(config config.ProcessorConfig) (Processor, error) {
return nil, err 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) { return &MIDIMessageCreate{config: config, ProcessFunc: func(ctx context.Context, payload any) (any, error) {
var channelBuffer bytes.Buffer var channelBuffer bytes.Buffer
@@ -179,7 +154,16 @@ func newMidiNoteOffCreate(config config.ProcessorConfig) (Processor, error) {
noteValue, err := strconv.ParseUint(noteBuffer.String(), 10, 8) 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 return payloadMessage, nil
}}, nil }}, nil
} }
@@ -188,16 +172,9 @@ func newMidiControlChangeCreate(config config.ProcessorConfig) (Processor, error
params := config.Params params := config.Params
channel, ok := params["channel"] channelString, err := params.GetString("channel")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.message.create channel error: %w", err)
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")
} }
channelTemplate, err := template.New("channel").Parse(channelString) channelTemplate, err := template.New("channel").Parse(channelString)
@@ -206,16 +183,9 @@ func newMidiControlChangeCreate(config config.ProcessorConfig) (Processor, error
return nil, err return nil, err
} }
control, ok := params["control"] controlString, err := params.GetString("control")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.message.create control error: %w", err)
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")
} }
controlTemplate, err := template.New("control").Parse(controlString) controlTemplate, err := template.New("control").Parse(controlString)
@@ -224,16 +194,9 @@ func newMidiControlChangeCreate(config config.ProcessorConfig) (Processor, error
return nil, err return nil, err
} }
value, ok := params["value"] valueString, err := params.GetString("value")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.message.create value error: %w", err)
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")
} }
valueTemplate, err := template.New("value").Parse(valueString) valueTemplate, err := template.New("value").Parse(valueString)
@@ -280,16 +243,9 @@ func newMidiProgramChangeCreate(config config.ProcessorConfig) (Processor, error
params := config.Params params := config.Params
channel, ok := params["channel"] channelString, err := params.GetString("channel")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.message.create channel error: %w", err)
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")
} }
channelTemplate, err := template.New("channel").Parse(channelString) channelTemplate, err := template.New("channel").Parse(channelString)
@@ -298,16 +254,9 @@ func newMidiProgramChangeCreate(config config.ProcessorConfig) (Processor, error
return nil, err return nil, err
} }
program, ok := params["program"] programString, err := params.GetString("program")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.message.create program error: %w", err)
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")
} }
programTemplate, err := template.New("program").Parse(programString) programTemplate, err := template.New("program").Parse(programString)
@@ -347,16 +296,9 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) { New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params params := config.Params
msgType, ok := params["type"] msgTypeString, err := params.GetString("type")
if err != nil {
if !ok { return nil, fmt.Errorf("midi.message.create type error: %w", err)
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")
} }
switch msgTypeString { switch msgTypeString {

View File

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

View File

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

View File

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

View File

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

View File

@@ -40,16 +40,9 @@ func init() {
Type: "osc.message.filter", Type: "osc.message.filter",
New: func(config config.ProcessorConfig) (Processor, error) { New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params params := config.Params
address, ok := params["address"] addressString, err := params.GetString("address")
if err != nil {
if !ok { return nil, fmt.Errorf("osc.message.filter address error: %w", err)
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")
} }
addressPattern := strings.ReplaceAll(addressString, "?", ".") addressPattern := strings.ReplaceAll(addressString, "?", ".")

View File

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

View File

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

View File

@@ -2,6 +2,7 @@ package processor
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
extism "github.com/extism/go-sdk" extism "github.com/extism/go-sdk"
@@ -44,44 +45,30 @@ func (se *ScriptWASM) Type() string {
func init() { func init() {
RegisterProcessor(ProcessorRegistration{ RegisterProcessor(ProcessorRegistration{
Type: "script.wasm", Type: "script.wasm",
New: func(config config.ProcessorConfig) (Processor, error) { New: func(processorConfig config.ProcessorConfig) (Processor, error) {
params := config.Params params := processorConfig.Params
path, ok := params["path"] pathString, err := params.GetString("path")
if err != nil {
if !ok { return nil, fmt.Errorf("script.wasm path error: %w", err)
return nil, fmt.Errorf("script.wasm requires a path parameter")
} }
pathString, ok := path.(string) functionString, err := params.GetString("function")
if err != nil {
if !ok { if errors.Is(err, config.ErrParamNotFound) {
return nil, fmt.Errorf("script.wasm path must be a string") functionString = "process"
} else {
return nil, fmt.Errorf("script.wasm function error: %w", err)
}
} }
functionString := "process" enableWasiBool, err := params.GetBool("enableWasi")
if err != nil {
function, ok := params["function"] if errors.Is(err, config.ErrParamNotFound) {
enableWasiBool = false
if ok { } else {
specificFunctionString, ok := function.(string) return nil, fmt.Errorf("script.wasm enableWasi error: %w", err)
if !ok {
return nil, fmt.Errorf("script.wasm function must be a string")
} }
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 = specificEnableWasi
} }
manifest := extism.Manifest{ manifest := extism.Manifest{
@@ -100,7 +87,7 @@ func init() {
return nil, err 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 ( import (
"bytes" "bytes"
"context" "context"
"errors" "fmt"
"text/template" "text/template"
"github.com/jwetzell/showbridge-go/internal/config" "github.com/jwetzell/showbridge-go/internal/config"
@@ -50,40 +50,19 @@ func init() {
New: func(config config.ProcessorConfig) (Processor, error) { New: func(config config.ProcessorConfig) (Processor, error) {
params := config.Params params := config.Params
preWait, ok := params["preWait"] preWaitNum, err := params.GetInt("preWait")
if err != nil {
if !ok { return nil, fmt.Errorf("sip.response.audio.create preWait error: %w", err)
return nil, errors.New("sip.response.audio.create requires a preWait parameter")
} }
preWaitNum, ok := preWait.(float64) postWaitNum, err := params.GetInt("postWait")
if err != nil {
if !ok { return nil, fmt.Errorf("sip.response.audio.create postWait error: %w", err)
return nil, errors.New("sip.response.audio.create preWait must be a number")
} }
postWait, ok := params["postWait"] audioFileString, err := params.GetString("audioFile")
if err != nil {
if !ok { return nil, fmt.Errorf("sip.response.audio.create audioFile error: %w", err)
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")
} }
audioFileTemplate, err := template.New("audioFile").Parse(audioFileString) audioFileTemplate, err := template.New("audioFile").Parse(audioFileString)

View File

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

View File

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

View File

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

View File

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

View File

@@ -199,7 +199,7 @@ func TestBadArtnetPacketFilter(t *testing.T) {
Type: 0, Type: 0,
}, },
params: map[string]any{}, 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", name: "opCode not a number",
@@ -217,7 +217,7 @@ func TestBadArtnetPacketFilter(t *testing.T) {
Type: 0, Type: 0,
}, },
params: map[string]any{"opCode": "100"}, 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", name: "no min param",
payload: "hello", payload: "hello",
params: map[string]any{"max": 10.0}, 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", name: "no max param",
payload: "hello", payload: "hello",
params: map[string]any{"min": 1.0}, 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", name: "min param not a number",
payload: "hello", payload: "hello",
params: map[string]any{"min": "1", "max": 10.0}, 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", name: "max param not a number",
payload: "hello", payload: "hello",
params: map[string]any{"min": 1.0, "max": "10"}, 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", name: "max less than min",

View File

@@ -104,7 +104,7 @@ func TestBadMIDIMessageFilter(t *testing.T) {
name: "no type param", name: "no type param",
params: map[string]any{}, params: map[string]any{},
payload: midi.NoteOn(1, 60, 127), 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", name: "non-string type param",
@@ -112,7 +112,7 @@ func TestBadMIDIMessageFilter(t *testing.T) {
"type": 123, "type": 123,
}, },
payload: "hello", 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", name: "non-midi message input",

View File

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

View File

@@ -108,7 +108,7 @@ func TestBadOSCMessageFilter(t *testing.T) {
name: "no address parameter", name: "no address parameter",
params: map[string]any{}, params: map[string]any{},
payload: osc.OSCMessage{Address: "/test"}, 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", name: "non-string address parameter",
@@ -116,7 +116,7 @@ func TestBadOSCMessageFilter(t *testing.T) {
"address": 123, "address": 123,
}, },
payload: osc.OSCMessage{Address: "/test"}, 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", name: "bad address pattern",

View File

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

View File

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

View File

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

View File

@@ -111,13 +111,13 @@ func TestBadStringSplit(t *testing.T) {
name: "missing separator param", name: "missing separator param",
payload: "part1,part2,part3", payload: "part1,part2,part3",
params: map[string]any{}, params: map[string]any{},
errorString: "string.split requires a separator", errorString: "string.split separator error: not found",
}, },
{ {
name: "non-string separator param", name: "non-string separator param",
payload: "part1,part2,part3", payload: "part1,part2,part3",
params: map[string]any{"separator": 123}, 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", name: "no-duration param",
payload: "hello", payload: "hello",
params: map[string]any{}, params: map[string]any{},
errorString: "time.sleep requires a duration parameter", errorString: "time.sleep duration error: not found",
}, },
{ {
name: "non-number duration param", name: "non-number duration param",
@@ -90,7 +90,7 @@ func TestBadTimeSleep(t *testing.T) {
params: map[string]any{ params: map[string]any{
"duration": "1000", "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", name: "no min param",
payload: "hello", payload: "hello",
params: map[string]any{"max": 10.0}, 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", name: "no max param",
payload: "hello", payload: "hello",
params: map[string]any{"min": 1.0}, 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", name: "min param not a number",
payload: "hello", payload: "hello",
params: map[string]any{"min": "1", "max": 10.0}, 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", name: "max param not a number",
payload: "hello", payload: "hello",
params: map[string]any{"min": 1.0, "max": "10"}, 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", name: "max less than min",

View File

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

View File

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

View File

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