-
Notifications
You must be signed in to change notification settings - Fork 8
/
xmlstruct.go
114 lines (100 loc) · 3.59 KB
/
xmlstruct.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Package xmlstruct generates Go structs from multiple XML documents.
package xmlstruct
import (
"encoding/xml"
"regexp"
"strings"
"unicode"
"golang.org/x/exp/constraints"
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
)
const (
DefaultAttrNameSuffix = ""
DefaultCharDataFieldName = "CharData"
DefaultElemNameSuffix = ""
DefaultFormatSource = true
DefaultHeader = "// This file is automatically generated. DO NOT EDIT."
DefaultTopLevelAttributes = false
DefaultIntType = "int"
DefaultNamedTypes = false
DefaultPackageName = "main"
DefaultPreserveOrder = false
DefaultTimeLayout = "2006-01-02T15:04:05Z"
DefaultUsePointersForOptionalFields = true
DefaultUseRawToken = false
)
var (
// TitleFirstRuneExportNameFunc returns name.Local with the initial rune
// capitalized.
TitleFirstRuneExportNameFunc = func(name xml.Name) string {
runes := []rune(name.Local)
runes[0] = unicode.ToUpper(runes[0])
return string(runes)
}
kebabOrSnakeCaseWordBoundaryRx = regexp.MustCompile(`[-_]+\pL`)
nonIdentifierRuneRx = regexp.MustCompile(`[^\pL\pN]+`)
// DefaultExportNameFunc returns name.Local with kebab- and snakecase words
// converted to camelcase and any Id suffix converted to ID.
DefaultExportNameFunc = func(name xml.Name) string {
localName := kebabOrSnakeCaseWordBoundaryRx.ReplaceAllStringFunc(name.Local, func(s string) string {
return strings.ToUpper(s[len(s)-1:])
})
localName = nonIdentifierRuneRx.ReplaceAllLiteralString(localName, "")
runes := []rune(localName)
runes[0] = unicode.ToUpper(runes[0])
if len(runes) > 1 && runes[len(runes)-2] == 'I' && runes[len(runes)-1] == 'd' {
runes[len(runes)-1] = 'D'
}
return string(runes)
}
)
var (
// IgnoreNamespaceNameFunc returns name with name.Space cleared. The same
// local name in different namespaces will be treated as identical names.
IgnoreNamespaceNameFunc = func(name xml.Name) xml.Name {
return xml.Name{
Local: name.Local,
}
}
// The IdentityNameFunc returns name unchanged. The same local name in
// different namespaces will be treated as distinct names.
IdentityNameFunc = func(name xml.Name) xml.Name {
return name
}
DefaultNameFunc = IgnoreNamespaceNameFunc
)
// An ExportNameFunc returns the exported Go identifier for the given xml.Name.
type ExportNameFunc func(xml.Name) string
// A NameFunc modifies xml.Names observed in the XML documents.
type NameFunc func(xml.Name) xml.Name
// observeOptions contains options for observing XML documents.
type observeOptions struct {
getOrder func() int
nameFunc NameFunc
timeLayout string
typeOrder map[xml.Name]int
topLevelAttributes bool
topLevelElements map[xml.Name]*element
useRawToken bool
}
// generateOptions contains options for generating Go source.
type generateOptions struct {
attrNameSuffix string
charDataFieldName string
elemNameSuffix string
exportNameFunc ExportNameFunc
header string
importPackageNames map[string]struct{}
intType string
namedTypes map[xml.Name]*element
preserveOrder bool
simpleTypes map[xml.Name]struct{}
usePointersForOptionalFields bool
}
// sortedKeys returns the keys of m in order.
func sortedKeys[M ~map[K]V, K constraints.Ordered, V any](m M) []K {
keys := maps.Keys(m)
slices.Sort(keys)
return keys
}