all repos

json2go @ 1609c23952004c5a160a5737c4ac8e9fac80292b

convert json to go type annotations
2 files changed, 43 insertions(+), 9 deletions(-)
feat: validate provided struct name
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2025-11-26 20:05:07 +0200
Change ID: nxznoqyxnmxwnuxnkzruyrvvptxluuwn
Parent: 7a527f3
M json2go.go

@@ -4,11 +4,16 @@ import (

"encoding/json" "errors" "fmt" + "regexp" "sort" "strings" ) -var ErrInvalidJSON = errors.New("invalid json") +var identRe = regexp.MustCompile(`^[A-Za-z_][A-Za-z0-9_]*$`) +var ( + ErrInvalidJSON = errors.New("invalid json") + ErrInvalidStructName = errors.New("invalid struct name") +) type Transformer struct { structName string

@@ -21,8 +26,11 @@

// Transform ... // todo: take io.Reader as input? // todo: output as io.Writer? -// todo: validate provided structName func (t *Transformer) Transform(structName, jsonStr string) (string, error) { + if !identRe.MatchString(structName) { + return "", ErrInvalidStructName + } + t.structName = structName var input any

@@ -65,7 +73,6 @@

} } -// todo: input shouldn't be map, to preserve it's order func (t *Transformer) buildStruct(input map[string]any) string { var fields strings.Builder for _, f := range mapToStructInput(input) {
M json2go_test.go

@@ -22,9 +22,10 @@ }

func TestTransformer_Transform(t *testing.T) { tests := map[string]struct { - input string - output string - err error + input string + output string + structName string + err error }{ "simple object": { input: `{"name": "Olex", "active": true, "age": 420}`,

@@ -37,6 +38,18 @@ },

"invalid json": { err: ErrInvalidJSON, input: `{"invalid":json}`, + }, + "invalid struct name, starts with number": { + err: ErrInvalidStructName, + structName: "1Name", + }, + "invalid struct name, has space": { + err: ErrInvalidStructName, + structName: "Name Name2", + }, + "invalid struct name, has non letter/number": { + err: ErrInvalidStructName, + structName: "Name$", }, "snake_case to CamelCase": { input: `{"first_name": "Bob", "last_name": "Bobberson"}`,

@@ -93,7 +106,12 @@

trans := NewTransformer() for tname, tt := range tests { t.Run(tname, func(t *testing.T) { - result, err := trans.Transform("Out", tt.input) + sn := "Out" + if tt.structName != "" { + sn = tt.structName + } + + result, err := trans.Transform(sn, tt.input) assertEqualErr(t, tt.err, err) assertEqual(t, tt.output, result) })

@@ -102,8 +120,17 @@ }

func assertEqualErr(t *testing.T, expected, actual error) { t.Helper() - if (expected != nil || actual != nil) && errors.Is(expected, actual) { - t.Errorf("expected: %v, got: %v\n", expected, actual) + if expected == nil && actual == nil { + return + } + + if expected == nil || actual == nil { + t.Errorf("expected: %v, got: %v", expected, actual) + return + } + + if !errors.Is(actual, expected) { + t.Errorf("expected error: %v, got: %v", expected, actual) } }