feat: support hex strings in parseInt/parseUint (by AI)
This commit is contained in:
parent
b3a4b5f13a
commit
7140e29b9e
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
.gemini/
|
||||
.ai/
|
||||
|
||||
.geminiignore
|
||||
.gemini
|
||||
/CODE-FULL.md
|
||||
|
||||
4
CHANGELOG-LATEST.md
Normal file
4
CHANGELOG-LATEST.md
Normal file
@ -0,0 +1,4 @@
|
||||
## [v1.2.9] - 2026-05-09
|
||||
### Changed
|
||||
- **移除第三方依赖**: 移除了对 `jsontag` 模块的依赖,统一使用标准库及自有基础设施对齐,增强了模块的独立性与长期稳定性。
|
||||
|
||||
286
CODE-SUMMARY.md
Normal file
286
CODE-SUMMARY.md
Normal file
@ -0,0 +1,286 @@
|
||||
### cast > cast.go
|
||||
```go
|
||||
|
||||
|
||||
|
||||
// If 泛型三元表达式
|
||||
func If[T any](condition bool, trueVal, falseVal T) T
|
||||
|
||||
|
||||
// In 泛型包含判断
|
||||
func In[T comparable](arr []T, val T) bool
|
||||
|
||||
|
||||
// As 忽略错误,返回零值 (消除摩擦)
|
||||
func As[T any](v T, err error) T
|
||||
|
||||
|
||||
func RealValue(v reflect.Value) reflect.Value
|
||||
|
||||
|
||||
// --- Core Cast Logic ---
|
||||
|
||||
var (
|
||||
timeType = reflect.TypeOf(time.Time{})
|
||||
)
|
||||
|
||||
// To 深度转换 (支持基础类型、Slice、Map、Struct 及 JSON 自动转换,零摩擦模式)
|
||||
func To[T any](v any) T
|
||||
|
||||
|
||||
// Convert 深度转换 (支持基础类型、Slice、Map、Struct 及 JSON 自动转换,原地更新)
|
||||
func Convert(dst, src any)
|
||||
|
||||
|
||||
func performRecursiveTo(src, dst reflect.Value)
|
||||
|
||||
|
||||
// 内部递归助手 (零分配/高性能设计)
|
||||
|
||||
func recursiveMapToStruct(src, dst reflect.Value)
|
||||
|
||||
|
||||
func recursiveStructToStruct(src, dst reflect.Value)
|
||||
|
||||
|
||||
func recursiveMapToMap(src, dst reflect.Value)
|
||||
|
||||
|
||||
func recursiveStructToMap(src, dst reflect.Value)
|
||||
|
||||
|
||||
func recursiveSliceToMap(src, dst reflect.Value)
|
||||
|
||||
|
||||
func recursiveSliceToSlice(src, dst reflect.Value)
|
||||
|
||||
|
||||
func ToTime(v any, format string) time.Time
|
||||
|
||||
|
||||
func reflectCast(value any, t reflect.Type) reflect.Value
|
||||
|
||||
|
||||
func reflectCastE(value any, t reflect.Type) (reflect.Value, error)
|
||||
|
||||
|
||||
func ToInt64E(v any) (int64, error)
|
||||
|
||||
|
||||
func ToUint64E(v any) (uint64, error)
|
||||
|
||||
|
||||
func ToFloat64E(v any) (float64, error)
|
||||
|
||||
|
||||
func isJSONText(v any) bool
|
||||
```
|
||||
|
||||
### cast > time.go
|
||||
```go
|
||||
|
||||
|
||||
|
||||
// TimeZone 定义了特定时区上下文下的时间操作
|
||||
type TimeZone struct {
|
||||
loc *time.Location
|
||||
}
|
||||
|
||||
// NewTimeZone 创建一个时区上下文
|
||||
func NewTimeZone(loc *time.Location) *TimeZone
|
||||
|
||||
|
||||
// DefaultTimeZone 全局默认时区,默认为本地时区
|
||||
var DefaultTimeZone = NewTimeZone(time.Local)
|
||||
|
||||
// SetDefaultTimeZone 修改全局默认时区
|
||||
func SetDefaultTimeZone(loc *time.Location)
|
||||
|
||||
|
||||
// 在包级别预先初始化 Replacer,0 额外分配
|
||||
var timeFormatReplacer = strings.NewReplacer(
|
||||
"YYYY", "2006", "YY", "06",
|
||||
"MM", "01", "M", "1",
|
||||
"DD", "02", "D", "2",
|
||||
"HH", "15", "hh", "03", "h", "3",
|
||||
"mm", "04", "ss", "05",
|
||||
"a", "pm", "A", "PM",
|
||||
"ZZ", "-0700", "Z", "-07:00",
|
||||
)
|
||||
|
||||
// ParseTime 将任意类型转换为 time.Time。
|
||||
// 支持:time.Time, 时间戳 (秒/毫秒/微秒/纳秒), RFC3339, JS 格式, 中文格式等。
|
||||
// 转换失败返回零值 time.Time{} 以保持 cast 的静默风格。
|
||||
func (tz *TimeZone) ParseTime(v any) time.Time
|
||||
|
||||
|
||||
var cnDateRegex = regexp.MustCompile(`(\d{2,4})?年?(\d{1,2})月(\d{1,2})日`)
|
||||
var cnTimeRegex = regexp.MustCompile(`(上午|下午)?(\d{1,2})(?:时|点|:)(\d{1,2})(?:分|:)(\d{1,2})?秒?`)
|
||||
|
||||
func (tz *TimeZone) parseCN(str string) time.Time
|
||||
|
||||
|
||||
// ParseTime 将任意类型转换为 time.Time。
|
||||
func ParseTime(v any) time.Time
|
||||
|
||||
|
||||
// FormatTime 格式化时间。
|
||||
// layout 支持: YYYY-MM-DD HH:mm:ss, YYYY/MM/DD, HH:mm 等直观格式。
|
||||
func (tz *TimeZone) FormatTime(layout string, v any) string
|
||||
|
||||
|
||||
// FormatTime 格式化时间。
|
||||
func FormatTime(layout string, v any) string
|
||||
|
||||
|
||||
// AddTime 时间加减 DSL。
|
||||
// 格式如: "+1Y-2M+3D", "+1h30m", "-1s"。
|
||||
// 单位支持: Y (年), M (月), D (天), h, m, s, ms, us, ns。
|
||||
func (tz *TimeZone) AddTime(expr string, v any) time.Time
|
||||
|
||||
|
||||
// AddTime 时间加减 DSL。
|
||||
func AddTime(expr string, v any) time.Time
|
||||
|
||||
|
||||
// Now 获取当前时间
|
||||
func (tz *TimeZone) Now() time.Time
|
||||
|
||||
|
||||
// Location 获取当前时区
|
||||
func (tz *TimeZone) Location() *time.Location
|
||||
|
||||
|
||||
// Now 获取当前时间
|
||||
func Now() time.Time
|
||||
|
||||
|
||||
// DescribeDuration 将时长转化为自然语言描述,例如 "1h 1m 1s"
|
||||
func (tz *TimeZone) DescribeDuration(d time.Duration) string
|
||||
|
||||
|
||||
// DescribeDuration 将时长转化为自然语言描述
|
||||
func DescribeDuration(d time.Duration) string
|
||||
|
||||
```
|
||||
|
||||
### cast > json_encoder.go
|
||||
```go
|
||||
|
||||
|
||||
|
||||
var (
|
||||
bufferPool = sync.Pool{
|
||||
New: func() any {
|
||||
return new(bytes.Buffer)
|
||||
},
|
||||
}
|
||||
encoderStructCache sync.Map
|
||||
)
|
||||
|
||||
type encoderFieldDescriptor struct {
|
||||
index int
|
||||
name string
|
||||
isAnonymous bool
|
||||
isTime bool
|
||||
timeFormat string
|
||||
keepKey bool
|
||||
}
|
||||
|
||||
type encoderStructDescriptor struct {
|
||||
fields []encoderFieldDescriptor
|
||||
}
|
||||
|
||||
type fastEncoder struct {
|
||||
buffer *bytes.Buffer
|
||||
desensitizeKeys map[string]bool
|
||||
}
|
||||
|
||||
func (encoder *fastEncoder) encode(value any) error
|
||||
|
||||
|
||||
func (encoder *fastEncoder) encodeValue(reflectValue reflect.Value, path string) error
|
||||
|
||||
|
||||
func (encoder *fastEncoder) writeTime(t time.Time, format string)
|
||||
|
||||
|
||||
func (encoder *fastEncoder) encodeSlice(reflectValue reflect.Value, path string) error
|
||||
|
||||
|
||||
func (encoder *fastEncoder) encodeMap(reflectValue reflect.Value, path string) error
|
||||
|
||||
|
||||
func getEncoderStructDescriptor(reflectType reflect.Type) *encoderStructDescriptor
|
||||
|
||||
|
||||
func (encoder *fastEncoder) encodeStruct(reflectValue reflect.Value, path string) error
|
||||
|
||||
|
||||
func (encoder *fastEncoder) encodeStructFields(reflectValue reflect.Value, path string, first *bool) error
|
||||
|
||||
|
||||
func (encoder *fastEncoder) writeString(str string)
|
||||
|
||||
|
||||
// 导出函数
|
||||
func fastToJSONBytes(value any, desensitizeKeys ...string) ([]byte, error)
|
||||
|
||||
```
|
||||
|
||||
### cast > json_decoder.go
|
||||
```go
|
||||
|
||||
|
||||
|
||||
var (
|
||||
structFieldMapCache sync.Map
|
||||
)
|
||||
|
||||
type decoderFieldDescriptor struct {
|
||||
index int
|
||||
isTime bool
|
||||
timeFormat string
|
||||
normalized string
|
||||
}
|
||||
|
||||
type decoderStructDescriptor struct {
|
||||
exactMatches map[string]decoderFieldDescriptor
|
||||
fields []decoderFieldDescriptor
|
||||
}
|
||||
|
||||
type decoder struct {
|
||||
data []byte
|
||||
pos int
|
||||
}
|
||||
|
||||
func (d *decoder) skipWhitespace()
|
||||
|
||||
|
||||
func (d *decoder) decode(value any) error
|
||||
|
||||
|
||||
func (d *decoder) decodeValue(reflectValue reflect.Value, timeFormat string) error
|
||||
|
||||
|
||||
func (d *decoder) skipValue() error
|
||||
|
||||
|
||||
// Frictionless Logic
|
||||
|
||||
func getDecoderFieldMap(reflectType reflect.Type) *decoderStructDescriptor
|
||||
|
||||
|
||||
func matchField(key string, descriptor *decoderStructDescriptor) (int, bool, string, bool)
|
||||
|
||||
|
||||
func normalizeEqual(raw string, normalized string) bool
|
||||
|
||||
|
||||
func normalizeKey(str string) string
|
||||
|
||||
|
||||
func fastUnmarshalJSONBytes(data []byte, value any) error
|
||||
|
||||
```
|
||||
|
||||
12
cast.go
12
cast.go
@ -527,6 +527,12 @@ func isComplexValue(v any) bool {
|
||||
}
|
||||
|
||||
func parseInt(s string) int64 {
|
||||
if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") {
|
||||
i, err := strconv.ParseInt(s, 0, 64)
|
||||
if err == nil {
|
||||
return i
|
||||
}
|
||||
}
|
||||
i, err := strconv.ParseInt(s, 10, 64)
|
||||
if err == nil {
|
||||
return i
|
||||
@ -538,6 +544,12 @@ func parseInt(s string) int64 {
|
||||
}
|
||||
|
||||
func parseUint(s string) uint64 {
|
||||
if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") {
|
||||
i, err := strconv.ParseUint(s, 0, 64)
|
||||
if err == nil {
|
||||
return i
|
||||
}
|
||||
}
|
||||
i, err := strconv.ParseUint(s, 10, 64)
|
||||
if err == nil {
|
||||
return i
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user