Compare commits
No commits in common. "main" and "v1.3.1" have entirely different histories.
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
|
||||
|
||||
```
|
||||
|
||||
14
README.md
14
README.md
@ -77,23 +77,13 @@ list, _ := cast.ToSlice[int]([]string{"1", "2", "3"})
|
||||
* `Ptr[T any](T) *T` —— 快速取指针。
|
||||
* `ArrayToBoolMap[T comparable]([]T) map[T]bool` —— 快速构建索引 Map。
|
||||
|
||||
6. **基础转换与时间 (直接调用,极致性能)**
|
||||
6. **基础转换 (直接调用,极致性能)**
|
||||
* `Int`, `Int64`, `Uint`, `Uint64`, `Float`, `Float64`, `String`, `Bool`, `Duration`
|
||||
* `RealValue(reflect.Value) reflect.Value` —— 递归获取指针或接口下的真实值。
|
||||
* `ParseTime(any) time.Time` —— 强大的时间解析,支持时间戳、RFC3339、JS 格式、紧凑格式及中文日期。
|
||||
* `FormatTime(layout, any) string` —— 直观格式化(如 YYYY-MM-DD HH:mm:ss)。
|
||||
* `AddTime(expr, any) time.Time` —— DSL 时间计算(如 +1Y-2M+3D)。
|
||||
* `DescribeDuration(time.Duration) string` —— 将时长转化为自然语言描述(如 1h 5m)。
|
||||
|
||||
7. **字符串与参数处理**
|
||||
* `Split(s, sep string) []string` —— 增强型分割,自动 Trim 并过滤空字符串。
|
||||
* `SplitArgs(string) []string` —— 命令行参数分割,支持引号与转义。
|
||||
* `JoinArgs([]string, sep string) string` —— 命令行参数合并,自动处理引号与转义。
|
||||
* `UniqueAppend(to []string, from ...any) []string` —— 去重追加。
|
||||
* `GetLowerName(string) string` | `GetUpperName(string) string` —— 首字母大小写转换工具。
|
||||
* `FixUpperCase([]byte, []string)` —— 针对 JSON Key 的特殊大小写修复工具。
|
||||
|
||||
8. **时区支持**
|
||||
7. **时区支持**
|
||||
* `DefaultTimeZone` —— 全局默认时区上下文。
|
||||
* `SetDefaultTimeZone(*time.Location)` —— 修改全局默认时区(影响所有 Convert 与 ToTime 操作)。
|
||||
* `DefaultTimeZone.Now()` —— 获取时区上下文下的当前时间。
|
||||
|
||||
@ -445,10 +445,7 @@ func getDecoderFieldMap(reflectType reflect.Type) *decoderStructDescriptor {
|
||||
|
||||
// 1. Tag
|
||||
tag := field.Tag.Get("json")
|
||||
if tag == "-" {
|
||||
continue
|
||||
}
|
||||
if tag != "" {
|
||||
if tag != "" && tag != "-" {
|
||||
parts := strings.Split(tag, ",")
|
||||
tagName := parts[0]
|
||||
for _, part := range parts {
|
||||
|
||||
@ -217,12 +217,9 @@ func getEncoderStructDescriptor(reflectType reflect.Type) *encoderStructDescript
|
||||
}
|
||||
|
||||
tag := field.Tag.Get("json")
|
||||
if tag == "-" {
|
||||
continue
|
||||
}
|
||||
fieldDesc.keepKey = strings.Contains(string(field.Tag), "keepKey")
|
||||
|
||||
if tag != "" {
|
||||
if tag != "" && tag != "-" {
|
||||
parts := strings.Split(tag, ",")
|
||||
for _, part := range parts {
|
||||
if strings.HasPrefix(part, "format=") {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user