Skip to content

Commit a11a9ab

Browse files
authored
add SentenceParser.OnBaseSentence (#114)
1 parent 5969ead commit a11a9ab

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

sentence.go

+10
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ type SentenceParser struct {
103103
// \g:2-3-1234*hh\!ABVDM,1,1,1,B,.....,0*hh
104104
// \g:3-3-1234*hh\$ABVSI,r3669961,1,013536.96326433,1386,-98,,*hh
105105
OnTagBlock func(tagBlock TagBlock) error
106+
107+
// OnBaseSentence is a callback for accessing/modifying the base sentence
108+
// before further parsing is done.
109+
OnBaseSentence func(sentence *BaseSentence) error
106110
}
107111

108112
func (p *SentenceParser) parseBaseSentence(raw string) (BaseSentence, error) {
@@ -264,6 +268,12 @@ func (p *SentenceParser) Parse(raw string) (Sentence, error) {
264268
return nil, err
265269
}
266270

271+
if p.OnBaseSentence != nil {
272+
if err := p.OnBaseSentence(&s); err != nil {
273+
return nil, err
274+
}
275+
}
276+
267277
// Custom parser allow overriding of existing parsers
268278
if parser, ok := p.CustomParsers[s.Type]; ok {
269279
return parser(s)

sentence_test.go

+64
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package nmea
33
import (
44
"encoding/hex"
55
"errors"
6+
"strings"
67
"testing"
78

89
"github.com/stretchr/testify/assert"
@@ -613,3 +614,66 @@ func TestSentenceParser_CheckCRC(t *testing.T) {
613614
})
614615
}
615616
}
617+
618+
func TestSentenceParser_OnBaseSentence(t *testing.T) {
619+
testErr := errors.New("this is a test")
620+
tests := []struct {
621+
name string
622+
fn func(*BaseSentence) error
623+
raw string
624+
sentence Sentence
625+
err error
626+
}{
627+
{
628+
name: "can modify prefix",
629+
fn: func(s *BaseSentence) error {
630+
if s.Type == "VDM" && strings.HasPrefix(s.Raw, "$") {
631+
s.Raw = "!" + s.Raw[1:]
632+
}
633+
return nil
634+
},
635+
raw: "\\s:somewhere,c:1720289719*4D\\$AIVDM,1,1,,A,,0*26",
636+
sentence: VDMVDO{
637+
BaseSentence: BaseSentence{
638+
Talker: "AI",
639+
Type: "VDM",
640+
Fields: []string{"1", "1", "", "A", "", "0"},
641+
Checksum: "26",
642+
Raw: "!AIVDM,1,1,,A,,0*26",
643+
TagBlock: TagBlock{
644+
Time: 1720289719,
645+
RelativeTime: 0,
646+
Destination: "",
647+
Grouping: "",
648+
LineCount: 0,
649+
Source: "somewhere",
650+
Text: "",
651+
},
652+
},
653+
NumFragments: 1,
654+
FragmentNumber: 1,
655+
MessageID: 0,
656+
Channel: "A",
657+
Payload: []uint8{},
658+
},
659+
},
660+
{
661+
name: "should return error",
662+
fn: func(_ *BaseSentence) error { return testErr },
663+
raw: "$GNRMC,142754.0,A,4302.539570,N,07920.379823,W,0.0,,070617,0.0,E,A*21",
664+
err: testErr,
665+
},
666+
}
667+
for _, tt := range tests {
668+
t.Run(tt.name, func(t *testing.T) {
669+
p := SentenceParser{OnBaseSentence: tt.fn}
670+
s, err := p.Parse(tt.raw)
671+
if tt.err == nil {
672+
assert.NoError(t, err)
673+
assert.Equal(t, tt.sentence, s)
674+
} else {
675+
assert.Equal(t, tt.err, err)
676+
}
677+
})
678+
}
679+
}

0 commit comments

Comments
 (0)