Skip to content

Commit

Permalink
fix: handle WithNamedTypes together with WithCompactTypes
Browse files Browse the repository at this point in the history
Fixes #44
  • Loading branch information
meblum authored and twpayne committed Aug 28, 2024
1 parent dac321d commit 66f7d7d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 2 deletions.
25 changes: 25 additions & 0 deletions element.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io"
"slices"
"strings"
)

// An element describes an observed XML element, its attributes, chardata, and
Expand All @@ -14,6 +15,7 @@ type element struct {
attrValues map[xml.Name]*value
charDataValue value
childElements map[xml.Name]*element
nestedCount int
childOrder map[xml.Name]int
name xml.Name
optionalChildren map[xml.Name]struct{}
Expand Down Expand Up @@ -107,6 +109,9 @@ FOR:
}
e.childElements[childName] = childElement
}
if childElement == e {
e.nestedCount++
}
if _, ok := e.childOrder[childName]; !ok {
e.childOrder[childName] = options.getOrder()
}
Expand Down Expand Up @@ -136,6 +141,15 @@ FOR:

// writeGoType writes e's Go type to w.
func (e *element) writeGoType(w io.Writer, options *generateOptions, indentPrefix string) error {
if options.compactTypes && e.isContainer() {
for _, v := range e.childElements {
if v == e {
fmt.Fprintf(w, "%s", e.charDataValue.goType(options))
return nil
}
}
}

if len(e.attrValues) == 0 && len(e.childElements) == 0 && (!e.root || !options.namedRoot) {
fmt.Fprintf(w, "%s", e.charDataValue.goType(options))
return nil
Expand Down Expand Up @@ -234,6 +248,9 @@ func (e *element) isContainer() bool {
func firstNotContainerElement(el *element) *element {
if el.isContainer() {
for _, v := range el.childElements {
if el == v {
return el
}
return firstNotContainerElement(v)
}
}
Expand All @@ -247,6 +264,9 @@ func exportedName(el *element, options *generateOptions) string {
func exportedNameWithoutSuffix(el *element, options *generateOptions) string {
if el.isContainer() && options.compactTypes {
for _, v := range el.childElements {
if el == v {
return options.exportNameFunc(el.name)
}
return exportedNameWithoutSuffix(v, options)
}
}
Expand All @@ -256,6 +276,11 @@ func exportedNameWithoutSuffix(el *element, options *generateOptions) string {
func attrName(el *element, compactTypes bool) string {
if el.isContainer() && compactTypes {
for _, v := range el.childElements {
if el == v {
s := el.name.Local + ">"
s += strings.Repeat(s, el.nestedCount)
return s[:len(s)-1]
}
return el.name.Local + ">" + attrName(v, true)
}
}
Expand Down
2 changes: 0 additions & 2 deletions generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"go/format"
"io"
"io/fs"
"maps"
"os"
"slices"
"sort"
Expand Down Expand Up @@ -285,7 +284,6 @@ func (g *Generator) Generate() ([]byte, error) {

var typeElements []*element
if g.namedTypes {
options.namedTypes = maps.Clone(g.typeElements)
options.namedTypes = make(map[xml.Name]*element)
for k, v := range g.typeElements {
if !options.compactTypes || !v.isContainer() || v.root {
Expand Down
27 changes: 27 additions & 0 deletions generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,33 @@ func TestGenerator(t *testing.T) {
"}",
),
},
{
name: "compact_named_types_container_child_equal_name",
options: []xmlstruct.GeneratorOption{
xmlstruct.WithImports(false),
xmlstruct.WithPackageName(""),
xmlstruct.WithHeader(""),
xmlstruct.WithCompactTypes(true),
xmlstruct.WithNamedTypes(true),
},
xmlStr: joinLines(
`<a>`,
` <b>`,
` <b>`,
` <b>`,
` </b>`,
` </b>`,
` </b>`,
` <b>`,
` </b>`,
`</a>`,
),
expectedStr: joinLines(
"type A struct {",
"\tB []struct{} `xml:\"b>b>b\"`",
"}",
),
},
} {
tc := tc
t.Run(tc.name, func(t *testing.T) {
Expand Down

0 comments on commit 66f7d7d

Please sign in to comment.