From 7140e29b9e515024126ed8ae17cec070fbe96cf6 Mon Sep 17 00:00:00 2001 From: Star <> Date: Tue, 12 May 2026 14:33:29 +0800 Subject: [PATCH] feat: support hex strings in parseInt/parseUint (by AI) --- .gitignore | 3 +- CHANGELOG-LATEST.md | 4 + CODE-SUMMARY.md | 286 ++++++++++++++++++++++++++++++++++++++++++++ cast.go | 12 ++ 4 files changed, 304 insertions(+), 1 deletion(-) create mode 100644 CHANGELOG-LATEST.md create mode 100644 CODE-SUMMARY.md diff --git a/.gitignore b/.gitignore index ca366db..c5ad6f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .gemini/ .ai/ - .geminiignore +.gemini +/CODE-FULL.md diff --git a/CHANGELOG-LATEST.md b/CHANGELOG-LATEST.md new file mode 100644 index 0000000..1498182 --- /dev/null +++ b/CHANGELOG-LATEST.md @@ -0,0 +1,4 @@ +## [v1.2.9] - 2026-05-09 +### Changed +- **移除第三方依赖**: 移除了对 `jsontag` 模块的依赖,统一使用标准库及自有基础设施对齐,增强了模块的独立性与长期稳定性。 + diff --git a/CODE-SUMMARY.md b/CODE-SUMMARY.md new file mode 100644 index 0000000..01e20aa --- /dev/null +++ b/CODE-SUMMARY.md @@ -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 + +``` + diff --git a/cast.go b/cast.go index cf031a1..8708ff2 100644 --- a/cast.go +++ b/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