Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions internal/pkg/ds/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,9 @@ type FlagDeclaration struct {
}

type PartialFieldDeclaration struct {
Name string // Имя части поля
Type string // Тип части поля
Name string // Имя части поля
Type string // Тип части поля
MappingKeyName string // Имя ключа в мепе модифицированных полей
}

type LinkedPackageDeclaration struct {
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/generator/tmpl/octopus/main.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ func (obj *{{ $PublicStructName }}) pack{{ $fstruct.Name }}PartialFields(op octo
{{ range $i, $f := $customMutator.PartialFields }}

func (obj *{{ $PublicStructName }}) Set{{ $customMutator.Name }}{{ $f.Name }}({{ $f.Name }} {{ $f.Type }}) error {
obj.Mutators.{{ $customMutator.Name }}.PartialFields["{{ $f.Name }}"] = {{ $f.Name }}
obj.Mutators.{{ $customMutator.Name }}.PartialFields["{{ $f.MappingKeyName }}"] = {{ $f.Name }}

if err := obj.pack{{ $fstruct.Name }}PartialFields(octopus.OpUpdate); err != nil {
return fmt.Errorf("pack {{ $customMutator.Name }}{{ $f.Name }}: %w", err)
Expand Down
28 changes: 14 additions & 14 deletions internal/pkg/parser/mutator_b_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,10 @@ func TestParseMutator(t *testing.T) {
Update: "updateFunc,param1,param2",
Replace: "replaceFunc",
PartialFields: []ds.PartialFieldDeclaration{
{Name: "Key", Type: "string"},
{Name: "Bar", Type: "ds.AppInfo"},
{Name: "BeerData", Type: "[]foo.Beer"},
{Name: "MapData", Type: "map[string]any"},
{Name: "Key", Type: "string", MappingKeyName: "Key"},
{Name: "Bar", Type: "ds.AppInfo", MappingKeyName: "Bar"},
{Name: "BeerData", Type: "[]foo.Beer", MappingKeyName: "beer_data"},
{Name: "MapData", Type: "map[string]any", MappingKeyName: "MapData"},
},
},
"SimpleTypeMutatorField": {
Expand Down Expand Up @@ -145,18 +145,18 @@ func TestParseMutator(t *testing.T) {
},
ImportStructFieldsMap: map[string][]ds.PartialFieldDeclaration{
"ds.AppInfo": {
{Name: "appName", Type: "string"},
{Name: "version", Type: "string"},
{Name: "buildTime", Type: "string"},
{Name: "buildOS", Type: "string"},
{Name: "buildCommit", Type: "string"},
{Name: "generateTime", Type: "string"},
{Name: "appName", Type: "string", MappingKeyName: "appName"},
{Name: "version", Type: "string", MappingKeyName: "version"},
{Name: "buildTime", Type: "string", MappingKeyName: "buildTime"},
{Name: "buildOS", Type: "string", MappingKeyName: "buildOS"},
{Name: "buildCommit", Type: "string", MappingKeyName: "buildCommit"},
{Name: "generateTime", Type: "string", MappingKeyName: "generateTime"},
},
"foo.Foo": {
{Name: "Key", Type: "string"},
{Name: "Bar", Type: "ds.AppInfo"},
{Name: "BeerData", Type: "[]foo.Beer"},
{Name: "MapData", Type: "map[string]any"},
{Name: "Key", Type: "string", MappingKeyName: "Key"},
{Name: "Bar", Type: "ds.AppInfo", MappingKeyName: "Bar"},
{Name: "BeerData", Type: "[]foo.Beer", MappingKeyName: "beer_data"},
{Name: "MapData", Type: "map[string]any", MappingKeyName: "MapData"},
},
},
},
Expand Down
37 changes: 35 additions & 2 deletions internal/pkg/parser/partialstruct.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"go/parser"
"go/token"
"path/filepath"
"strings"

"github.com/mailru/activerecord/internal/pkg/arerror"
"github.com/mailru/activerecord/internal/pkg/ds"
Expand Down Expand Up @@ -35,14 +36,24 @@ func parseStructFields(dst *ds.RecordPackage, gen *ast.GenDecl, name, pkgName st
continue
}

fName, ignore, err := parseTag(field)
if err != nil {
return nil, &arerror.ErrParseTypeStructDecl{Name: currType.Name.Name, Err: err}
}

if ignore {
continue
}

t, err := ParseFieldType(dst, name, pkgName, field.Type)
if err != nil {
return nil, &arerror.ErrParseTypeFieldStructDecl{Name: name, FieldType: field.Names[0].Name, Err: err}
}

field := ds.PartialFieldDeclaration{
Name: field.Names[0].Name,
Type: t,
Name: field.Names[0].Name,
Type: t,
MappingKeyName: fName,
}

partialFields = append(partialFields, field)
Expand All @@ -55,6 +66,28 @@ func parseStructFields(dst *ds.RecordPackage, gen *ast.GenDecl, name, pkgName st
return nil, nil
}

// parseTag parse tag with format `ar: "name,[ignore]"`. tag is optional
func parseTag(field *ast.Field) (name string, ignore bool, err error) {
name = field.Names[0].Name

if field.Tag == nil {
return name, false, nil
}

tagParam, parseErr := splitTag(field, NoCheckFlag, map[TagNameType]ParamValueRule{})
if parseErr != nil {
return "", false, parseErr
}

if len(tagParam) > 0 {
k := strings.Split(tagParam[0][0], ",")
name = k[0]
ignore = len(k) > 1 && strings.Contains(tagParam[0][0], "ignore")
}

return name, ignore, err
}

func ParsePartialStructFields(dst *ds.RecordPackage, name, pkgName, path string) ([]ds.PartialFieldDeclaration, error) {
relPath, err := filepath.Rel(dst.Namespace.ModuleName, path)
if err != nil {
Expand Down
6 changes: 4 additions & 2 deletions internal/pkg/parser/partialstruct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import (
)

type Foo struct {
Bar int
Bar int `ar:"bar"`
Other string `ar:"bar,ignore"`
Other2 string `ar:",ignore"`
}

func TestParsePartialStructFields(t *testing.T) {
Expand Down Expand Up @@ -41,7 +43,7 @@ func TestParsePartialStructFields(t *testing.T) {
path: ".",
},
want: []ds.PartialFieldDeclaration{
{Name: "Bar", Type: "int"},
{Name: "Bar", Type: "int", MappingKeyName: "bar"},
},
wantErr: false,
},
Expand Down
3 changes: 2 additions & 1 deletion internal/pkg/parser/testdata/foo/foo.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type Beer struct{}
type Foo struct {
Key string
Bar ds.AppInfo
BeerData []Beer
BeerData []Beer `ar:"beer_data"`
MapData map[string]any
Other map[string]any `ar:",ignore"`
}
24 changes: 20 additions & 4 deletions internal/pkg/parser/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,31 @@ func splitTag(field *ast.Field, checkFlag uint32, rule map[TagNameType]ParamValu
return nil, arerror.ErrParseTagSplitAbsent
}

if !strings.HasPrefix(field.Tag.Value, "`ar:\"") {
tag := searchARTag(field)

if checkFlag&NoCheckFlag != 0 && tag == "" {
return [][]string{}, nil
}

if checkFlag&CheckFlagEmpty != 0 && (tag == "" || tag == "`ar:\"\"`") {
return nil, arerror.ErrParseTagInvalidFormat
}

if checkFlag&CheckFlagEmpty != 0 && field.Tag.Value == "`ar:\"\"`" {
return nil, arerror.ErrParseTagSplitEmpty
idx := strings.LastIndex(tag, "ar:\"")

return splitParam(tag[idx+3:len(tag)-1], rule)
}

func searchARTag(field *ast.Field) string {
tags := strings.Split(field.Tag.Value, " ")

for _, tag := range tags {
if strings.Contains(tag, "ar:\"") {
return tag
}
}

return splitParam(field.Tag.Value[4:len(field.Tag.Value)-1], rule)
return ""
}

func splitParam(str string, rule map[TagNameType]ParamValueRule) ([][]string, error) {
Expand Down
15 changes: 9 additions & 6 deletions internal/pkg/parser/utils_w_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,9 @@ func Test_splitTag(t *testing.T) {
{
name: "emptytag", wantErr: false,
args: args{
field: &ast.Field{Tag: &ast.BasicLit{Value: "`ar:\"\"`"}},
rule: map[TagNameType]ParamValueRule{},
field: &ast.Field{Tag: &ast.BasicLit{Value: "`ar:\"\"`"}},
rule: map[TagNameType]ParamValueRule{},
checkFlag: NoCheckFlag,
},
want: [][]string{},
},
Expand All @@ -193,16 +194,18 @@ func Test_splitTag(t *testing.T) {
{
name: "tagnoprefix", wantErr: true,
args: args{
field: &ast.Field{Tag: &ast.BasicLit{Value: "dsjfgsadkjgfdskj"}},
rule: map[TagNameType]ParamValueRule{},
field: &ast.Field{Tag: &ast.BasicLit{Value: "dsjfgsadkjgfdskj"}},
checkFlag: CheckFlagEmpty,
rule: map[TagNameType]ParamValueRule{},
},
want: nil,
},
{
name: "tag", wantErr: false,
args: args{
field: &ast.Field{Tag: &ast.BasicLit{Value: "`ar:\"a:b;c:d;d:r,t\"`"}},
rule: map[TagNameType]ParamValueRule{},
field: &ast.Field{Tag: &ast.BasicLit{Value: "`ar:\"a:b;c:d;d:r,t\"`"}},
rule: map[TagNameType]ParamValueRule{},
checkFlag: CheckFlagEmpty,
},
want: [][]string{{"a", "b"}, {"c", "d"}, {"d", "r,t"}},
},
Expand Down