-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathxmlstruct.go
157 lines (141 loc) · 4.87 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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Package xmlstruct generates Go structs from multiple XML documents.
package xmlstruct
import (
"cmp"
"encoding/xml"
"regexp"
"slices"
"strings"
"unicode"
)
const (
DefaultAttrNameSuffix = ""
DefaultCharDataFieldName = "CharData"
DefaultElemNameSuffix = ""
DefaultFormatSource = true
DefaultHeader = "// Code generated by goxmlstruct. DO NOT EDIT."
DefaultTopLevelAttributes = false
DefaultImports = true
DefaultIntType = "int"
DefaultNamedRoot = false
DefaultNamedTypes = false
DefaultCompactTypes = false
DefaultPackageName = "main"
DefaultPreserveOrder = false
DefaultTimeLayout = "2006-01-02T15:04:05Z"
DefaultUsePointersForOptionalFields = true
DefaultUseRawToken = false
DefaultEmptyElements = true
)
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 UpperCamelCase 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)
}
// DefaultUnexportNameFunc returns name.Local with kebab- and snakecase words
// converted to lowerCamelCase
// Any ID prefix is converted to id, and any Id suffix converted to ID.
DefaultUnexportNameFunc = 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.ToLower(runes[0])
if len(runes) > 1 {
if runes[len(runes)-2] == 'I' && runes[len(runes)-1] == 'd' {
runes[len(runes)-1] = 'D'
}
if runes[0] == 'i' && runes[1] == 'D' {
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
exportTypeNameFunc ExportNameFunc
header string
importPackageNames map[string]struct{}
intType string
namedRoot bool
namedTypes map[xml.Name]*element
compactTypes bool
preserveOrder bool
simpleTypes map[xml.Name]struct{}
usePointersForOptionalFields bool
emptyElements bool
}
func mapKeys[M ~map[K]V, K comparable, V any](m M) []K {
keys := make([]K, 0, len(m))
for k := range m {
keys = append(keys, k)
}
return keys
}
func mapValues[M ~map[K]V, K comparable, V any](m M) []V {
values := make([]V, 0, len(m))
for _, v := range m {
values = append(values, v)
}
return values
}
// sortedKeys returns the keys of m in order.
func sortedKeys[M ~map[K]V, K cmp.Ordered, V any](m M) []K {
keys := mapKeys(m)
slices.Sort(keys)
return keys
}