feat: parser error cases & generator skeleton

This commit is contained in:
Mark Puha 2025-06-05 20:16:00 +02:00
parent 27e661d68e
commit d96900ba17
5 changed files with 175 additions and 0 deletions

View file

@ -0,0 +1,14 @@
package junktag
type Generator interface {
Generate() []byte
}
type newGenerator func(string) (Generator, error)
type BytesGenerator struct {
}
func (b *BytesGenerator) Generate() []byte {
return nil
}

View file

@ -0,0 +1,87 @@
package junktag
import (
"fmt"
"regexp"
"strings"
)
type Enum string
const (
EnumBytes Enum = "b"
EnumCounter Enum = "c"
EnumTimestamp Enum = "t"
EnumRandomBytes Enum = "r"
EnumWaitTimeout Enum = "wt"
EnumWaitResponse Enum = "wr"
)
var validEnum = map[Enum]newGenerator{
EnumBytes: func(s string) (Generator, error) { return &BytesGenerator{}, nil },
EnumCounter: func(s string) (Generator, error) { return &BytesGenerator{}, nil },
EnumTimestamp: func(s string) (Generator, error) { return &BytesGenerator{}, nil },
EnumRandomBytes: func(s string) (Generator, error) { return &BytesGenerator{}, nil },
EnumWaitTimeout: func(s string) (Generator, error) { return &BytesGenerator{}, nil },
EnumWaitResponse: func(s string) (Generator, error) { return &BytesGenerator{}, nil },
}
type Foo struct {
x []Generator
}
type Tag struct {
Name Enum
Param string
}
func parseTags(input string) ([]Tag, error) {
// Regular expression to match <tagname optional_param>
re := regexp.MustCompile(`([a-zA-Z]+)(?:\s+([^>]+))?>`)
matches := re.FindAllStringSubmatch(input, -1)
tags := make([]Tag, 0, len(matches))
for _, match := range matches {
tag := Tag{
Name: Enum(match[1]),
}
if len(match) > 2 && match[2] != "" {
tag.Param = strings.TrimSpace(match[2])
}
tags = append(tags, tag)
}
return tags, nil
}
func Parse(input string) (Foo, error) {
inputSlice := strings.Split(input, "<")
fmt.Printf("%v\n", inputSlice)
if len(inputSlice) <= 1 {
return Foo{}, fmt.Errorf("empty input: %s", input)
}
for _, inputParam := range inputSlice[1:] {
if len(inputParam) == 1 {
return Foo{}, fmt.Errorf("empty tag in input: %s", inputSlice)
} else if strings.Count(inputParam, ">") != 1 {
return Foo{}, fmt.Errorf("ill formated input: %s", input)
}
tags, _ := parseTags(inputParam)
for _, tag := range tags {
fmt.Printf("Tag: %s, Param: %s\n", tag.Name, tag.Param)
gen, ok := validEnum[tag.Name]
if !ok {
return Foo{}, fmt.Errorf("invalid tag")
}
_, err := gen(tag.Param)
if err != nil {
return Foo{}, fmt.Errorf("")
}
}
}
return Foo{}, nil
}

View file

@ -0,0 +1,60 @@
package junktag
import (
"fmt"
"testing"
"github.com/stretchr/testify/require"
)
func TestParse(t *testing.T) {
type args struct {
input string
}
tests := []struct {
name string
args args
wantErr error
}{
{
name: "empty",
args: args{input: ""},
wantErr: fmt.Errorf("ill formated input"),
},
{
name: "extra >",
args: args{input: "<b 0xf6ab3267fa><c>>"},
wantErr: fmt.Errorf("ill formated input"),
},
{
name: "extra <",
args: args{input: "<<b 0xf6ab3267fa><c>"},
wantErr: fmt.Errorf("ill formated input"),
},
{
name: "empty <>",
args: args{input: "<><b 0xf6ab3267fa><c>"},
wantErr: fmt.Errorf("empty tag in input"),
},
{
name: "invalid tag",
args: args{input: "<q 0xf6ab3267fa>"},
wantErr: fmt.Errorf("invalid tag"),
},
{
name: "valid",
args: args{input: "<b 0xf6ab3267fa><c><b 0xf6ab><t><r 10><wt 10>"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := Parse(tt.args.input)
// TODO: ErrorAs doesn't work as you think
// if tt.wantErr != nil {
require.ErrorAs(t, err, &tt.wantErr)
// return
// }
})
}
}

4
go.mod
View file

@ -3,6 +3,7 @@ module github.com/amnezia-vpn/amneziawg-go
go 1.24
require (
github.com/stretchr/testify v1.10.0
github.com/tevino/abool/v2 v2.1.0
golang.org/x/crypto v0.36.0
golang.org/x/net v0.37.0
@ -12,6 +13,9 @@ require (
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/time v0.9.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

10
go.sum
View file

@ -1,7 +1,13 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tevino/abool/v2 v2.1.0 h1:7w+Vf9f/5gmKT4m4qkayb33/92M+Um45F2BkHOR+L/c=
github.com/tevino/abool/v2 v2.1.0/go.mod h1:+Lmlqk6bHDWHqN1cbxqhwEAwMPXgc8I1SDEamtseuXY=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
@ -16,5 +22,9 @@ golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gvisor.dev/gvisor v0.0.0-20250130013005-04f9204697c6 h1:6B7MdW3OEbJqOMr7cEYU9bkzvCjUBX/JlXk12xcANuQ=
gvisor.dev/gvisor v0.0.0-20250130013005-04f9204697c6/go.mod h1:5DMfjtclAbTIjbXqO1qCe2K5GKKxWz2JHvCChuTcJEM=