mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
This pull request standardizes the use of the Go 1.18+ `any` type alias
instead of `interface{}` throughout the codebase. The change improves
code readability and aligns with modern Go best practices. The update
touches many files, including core data structures, code generation
templates, logging utilities, and test data, ensuring consistency across
all usages.
**Type alias migration to `any`:**
* Replaced all instances of `interface{}` with `any` in core data
structures such as `garray` and in generated model structs (e.g.,
`TableUser`, `User1`, `User2`) to modernize type usage.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[3]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[4]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[5]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[6]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
* Updated function signatures, method parameters, and return types from
`interface{}` to `any` in various parts of the codebase, including code
generation, service logic, and logging utilities (e.g., `mlog`).
[[1]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[2]](diffhunk://#diff-2b1953fb78cf3593d8c2c7d911e95b65fd0b847c30ed0b4d167d16fe6d781235L54-R74)
[[3]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[4]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
[[5]](diffhunk://#diff-c5d51d56f487779a2b6207c7ad26c7a20bbadcc846ce094fe60ab4cabff58c51L107-R107)
[[6]](diffhunk://#diff-f96e6a9fdb416eb1804ceaba1fe0ac637bff22c43837f8bb849c2366ce72d4a1L116-R121)
[[7]](diffhunk://#diff-f94c83a1b08ae060d9346f4a6031fc4a7b9a0b894e02d9afaa09018b6598eac0L112-R112)
[[8]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L36-R36)
[[9]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L74-R74)
[[10]](diffhunk://#diff-748b11dbe8828dd4c040ec23cae0b8fe57ecf0a2d1b7694ea39102294e633c64L96-R96)
**Generated code and templates:**
* Adjusted generated files and code generation templates to output `any`
instead of `interface{}` for relevant struct fields and function
signatures, ensuring that new code generation aligns with the updated
convention.
[[1]](diffhunk://#diff-6c19859cb32c7516ea95ddc8f8235460818eb2f24d2204308e0d9e1b19e7d90fL15-R19)
[[2]](diffhunk://#diff-a15ba2f5e830b4833c47b902515a4f9e5a4f83a3707698f3229b307ec3776b41L15-R18)
[[3]](diffhunk://#diff-52e0837e84d49221d1b810d88fdf78221f36cffcd664fb42f8aba49a79b974dcL15-R19)
[[4]](diffhunk://#diff-11c3457d1a23a4ca6ecd00d6b856289774936b6a708384cf03aff164044e7546L15-R19)
[[5]](diffhunk://#diff-2cff9cf8e6a0cc34087326d8c8149c3bbaf74c76fdbdf5a73daed13cc04249e1L15-R19)
[[6]](diffhunk://#diff-175edfeea54490b8fe4e18ffcbea5835efaf8f0b8acf623359073987cae7eb76L48-R55)
[[7]](diffhunk://#diff-e001b7a4b63603b9b14f00de78a4d570bb76c5f57d856a24643f071032e12356L66-R73)
[[8]](diffhunk://#diff-5582954e8a9983988dc8854ad82067fb2ac6269b988e07357ad8db1dfec5f1a0L39-R41)
**Container and utility updates:**
* Refactored the `garray` container implementation and related
constructors/methods to use `[]any` instead of `[]interface{}`, along
with corresponding function signatures.
[[1]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L31-R31)
[[2]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L52-R52)
[[3]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L62-R62)
[[4]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L73-R86)
[[5]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L96-R97)
[[6]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L107-R114)
[[7]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L124-R124)
[[8]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L135-R143)
[[9]](diffhunk://#diff-3a1259e160a4dfa5fe49dfe739fbdb986c0d0a2220a709882ea48d3ae1b8f911L167-R167)
These changes collectively modernize the codebase and prepare it for
future Go developments by using the idiomatic `any` type.
131 lines
3.6 KiB
Go
131 lines
3.6 KiB
Go
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
|
|
//
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
// If a copy of the MIT was not distributed with this file,
|
|
// You can obtain one at https://github.com/gogf/gf.
|
|
|
|
// Package gxml provides accessing and converting for XML content.
|
|
package gxml
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/clbanning/mxj/v2"
|
|
|
|
"github.com/gogf/gf/v2/encoding/gcharset"
|
|
"github.com/gogf/gf/v2/errors/gerror"
|
|
"github.com/gogf/gf/v2/text/gregex"
|
|
)
|
|
|
|
// Decode parses `content` into and returns as map.
|
|
func Decode(content []byte) (map[string]any, error) {
|
|
res, err := convert(content)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
m, err := mxj.NewMapXml(res)
|
|
if err != nil {
|
|
err = gerror.Wrapf(err, `mxj.NewMapXml failed`)
|
|
}
|
|
return m, err
|
|
}
|
|
|
|
// DecodeWithoutRoot parses `content` into a map, and returns the map without root level.
|
|
func DecodeWithoutRoot(content []byte) (map[string]any, error) {
|
|
res, err := convert(content)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
m, err := mxj.NewMapXml(res)
|
|
if err != nil {
|
|
err = gerror.Wrapf(err, `mxj.NewMapXml failed`)
|
|
return nil, err
|
|
}
|
|
for _, v := range m {
|
|
if r, ok := v.(map[string]any); ok {
|
|
return r, nil
|
|
}
|
|
}
|
|
return m, nil
|
|
}
|
|
|
|
// XMLEscapeChars forces escaping invalid characters in attribute and element values.
|
|
// NOTE: this is brute force with NO interrogation of '&' being escaped already; if it is
|
|
// then '&' will be re-escaped as '&'.
|
|
//
|
|
/*
|
|
The values are:
|
|
" "
|
|
' '
|
|
< <
|
|
> >
|
|
& &
|
|
*/
|
|
//
|
|
// Note: if XMLEscapeCharsDecoder(true) has been called - or the default, 'false,' value
|
|
// has been toggled to 'true' - then XMLEscapeChars(true) is ignored. If XMLEscapeChars(true)
|
|
// has already been called before XMLEscapeCharsDecoder(true), XMLEscapeChars(false) is called
|
|
// to turn escape encoding on mv.Xml, etc., to prevent double escaping ampersands, '&'.
|
|
func XMLEscapeChars(b ...bool) {
|
|
mxj.XMLEscapeChars(b...)
|
|
}
|
|
|
|
// Encode encodes map `m` to an XML format content as bytes.
|
|
// The optional parameter `rootTag` is used to specify the XML root tag.
|
|
func Encode(m map[string]any, rootTag ...string) ([]byte, error) {
|
|
b, err := mxj.Map(m).Xml(rootTag...)
|
|
if err != nil {
|
|
err = gerror.Wrapf(err, `mxj.Map.Xml failed`)
|
|
}
|
|
return b, err
|
|
}
|
|
|
|
// EncodeWithIndent encodes map `m` to an XML format content as bytes with indent.
|
|
// The optional parameter `rootTag` is used to specify the XML root tag.
|
|
func EncodeWithIndent(m map[string]any, rootTag ...string) ([]byte, error) {
|
|
b, err := mxj.Map(m).XmlIndent("", "\t", rootTag...)
|
|
if err != nil {
|
|
err = gerror.Wrapf(err, `mxj.Map.XmlIndent failed`)
|
|
}
|
|
return b, err
|
|
}
|
|
|
|
// ToJson converts `content` as XML format into JSON format bytes.
|
|
func ToJson(content []byte) ([]byte, error) {
|
|
res, err := convert(content)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
mv, err := mxj.NewMapXml(res)
|
|
if err == nil {
|
|
return mv.Json()
|
|
}
|
|
err = gerror.Wrap(err, `mxj.NewMapXml failed`)
|
|
return nil, err
|
|
}
|
|
|
|
// convert does convert the encoding of given XML content from XML root tag into UTF-8 encoding content.
|
|
func convert(xml []byte) (res []byte, err error) {
|
|
var (
|
|
patten = `<\?xml.*encoding\s*=\s*['|"](.*?)['|"].*\?>`
|
|
matchStr, _ = gregex.MatchString(patten, string(xml))
|
|
xmlEncode = "UTF-8"
|
|
)
|
|
if len(matchStr) == 2 {
|
|
xmlEncode = matchStr[1]
|
|
}
|
|
xmlEncode = strings.ToUpper(xmlEncode)
|
|
res, err = gregex.Replace(patten, []byte(""), xml)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if xmlEncode != "UTF-8" && xmlEncode != "UTF8" {
|
|
dst, err := gcharset.Convert("UTF-8", xmlEncode, string(res))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
res = []byte(dst)
|
|
}
|
|
return res, nil
|
|
}
|