287 lines
5.8 KiB
Markdown
287 lines
5.8 KiB
Markdown
|
|
### 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
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
|