From 0b5a917e404b172a43a2dbd5f520f81fe71c5b8c Mon Sep 17 00:00:00 2001 From: saji Date: Thu, 7 Mar 2024 13:30:15 -0600 Subject: [PATCH] add JSON line parser, rename logparsers --- cmd/skylabify/skylabify.go | 2 +- internal/logparsers/parsers.go | 31 ++++++++++++++-------- internal/logparsers/parsers_test.go | 40 +++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 12 deletions(-) diff --git a/cmd/skylabify/skylabify.go b/cmd/skylabify/skylabify.go index 91f6ef6..5f37f90 100644 --- a/cmd/skylabify/skylabify.go +++ b/cmd/skylabify/skylabify.go @@ -92,7 +92,7 @@ func run(ctx *cli.Context) (err error) { fileReader := bufio.NewReader(istream) - var pfun logparsers.BusParserFunc + var pfun logparsers.BusEventParser pfun, ok := logparsers.ParsersMap[ctx.String("format")] if !ok { diff --git a/internal/logparsers/parsers.go b/internal/logparsers/parsers.go index f118dfe..63a05c7 100644 --- a/internal/logparsers/parsers.go +++ b/internal/logparsers/parsers.go @@ -2,6 +2,7 @@ package logparsers import ( "encoding/hex" + "encoding/json" "fmt" "regexp" "strconv" @@ -35,10 +36,10 @@ func NewFormatError(msg string, err error) error { return &FormatError{msg: msg, err: err} } -// type LineParserFunc is a function that takes a string +// type CanFrameParser is a function that takes a string // and returns a can frame. This is useful for common // can dump formats. -type LineParserFunc func(string) (can.Frame, time.Time, error) +type CanFrameParser func(string) (can.Frame, time.Time, error) var candumpRegex = regexp.MustCompile(`^\((\d+)\.(\d{6})\) \w+ (\w+)#(\w+)$`) @@ -157,20 +158,27 @@ func parseTelemLogLine(line string) (frame can.Frame, ts time.Time, err error) { } -// BusParserFunc is a function that takes a string and returns a busevent. -type BusParserFunc func(string) (skylab.BusEvent, error) +// BusEventParser is a function that takes a string and returns a busevent. +type BusEventParser func(string) (skylab.BusEvent, error) -// parserBusEventMapper takes a line parser (that returns a can frame) +// skylabify JSON parser. +func parseSkylabifyLogLine(input string) (skylab.BusEvent, error) { + var b = skylab.BusEvent{} + err := json.Unmarshal([]byte(input), &b) + return b, err +} + +// frameParseToBusEvent takes a line parser (that returns a can frame) // and makes it return a busEvent instead. -func parserBusEventMapper(f LineParserFunc) BusParserFunc { +func frameParseToBusEvent(fun CanFrameParser) BusEventParser { return func(s string) (skylab.BusEvent, error) { var b = skylab.BusEvent{} - f, ts, err := f(s) + frame, ts, err := fun(s) if err != nil { return b, err } b.Timestamp = ts - b.Data, err = skylab.FromCanFrame(f) + b.Data, err = skylab.FromCanFrame(frame) if err != nil { return b, err } @@ -179,7 +187,8 @@ func parserBusEventMapper(f LineParserFunc) BusParserFunc { } } -var ParsersMap = map[string]BusParserFunc{ - "telem": parserBusEventMapper(parseTelemLogLine), - "candump": parserBusEventMapper(parseCanDumpLine), +var ParsersMap = map[string]BusEventParser{ + "telem": frameParseToBusEvent(parseTelemLogLine), + "candump": frameParseToBusEvent(parseCanDumpLine), + "json": parseSkylabifyLogLine, } diff --git a/internal/logparsers/parsers_test.go b/internal/logparsers/parsers_test.go index 6c5d1a6..c7770e2 100644 --- a/internal/logparsers/parsers_test.go +++ b/internal/logparsers/parsers_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/kschamplin/gotelem/internal/can" + "github.com/kschamplin/gotelem/skylab" ) func Test_parseCanDumpLine(t *testing.T) { @@ -170,3 +171,42 @@ func Test_parseTelemLogLine_errors(t *testing.T) { }) } } + +func Test_parseSkylabifyLogLine(t *testing.T) { + type args struct { + input string + } + tests := []struct { + name string + args args + want skylab.BusEvent + wantErr bool + }{ + { + name: "basic test", + args: args{ + input: `{"ts":1685141873612,"id":259,"name":"wsl_velocity","data":{"motor_velocity":89.97547,"vehicle_velocity":2.38853}}`}, + want: skylab.BusEvent{ + Timestamp: time.UnixMilli(1685141873612), + Name: "wsl_velocity", + Data: &skylab.WslVelocity{ + MotorVelocity: 89.97547, + VehicleVelocity: 2.38853, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := parseSkylabifyLogLine(tt.args.input) + if (err != nil) != tt.wantErr { + t.Errorf("parseSkylabifyLogLine() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("parseSkylabifyLogLine() = %v, want %v", got, tt.want) + } + }) + } +}