支持结构体嵌套

This commit is contained in:
coward 2022-01-13 16:38:46 +08:00
parent 48e0a20ec2
commit f8217f92df
3 changed files with 199 additions and 4 deletions

View File

@ -5,13 +5,17 @@ dateparse time by struct tag
WithTagName() // 自定义你想要使用的tag名称默认为dateFormat
WithDefaultTagValue() // 定义这个tag的默认值默认为 default
WithDefaultFormat() // 定义时间格式化样式,默认为 2006-01-02 15:04:05
WithEmptyValue() // 定义一个空值返回,当指定结构体的指定字段为空值时,返回你想要的空值,默认为 `""`
注意: 暂不支持结构体嵌套操作
WithEmptyValue() // 定义一个空值返回,当指定结构体的指定字段为空值时,返回你想要的空值,默认为 `""`
## install&安装
```go
go get github.com/cowardmrx/dateparse_tag
```
### attention&&注意
```go
Parse(in,out interface{}) // 该方法已经弃用,但是仍然可以使用,不建议使用
Format(in interface{}) // 该方法已经替代Parse()方法支持嵌套结构体in 参数请使用指针传递
```
## use&使用
```go
type User struct {
@ -37,4 +41,63 @@ func TestNewDateParseTag(t *testing.T) {
// old user : &{张三 2022-01-12 14:10:17.1867047 +0800 CST m=+0.003444301}
// new user &{张三 2022-01-12 14:10:17}
type User struct {
Name string `json:"name"`
BirthDay string `json:"birth_day" format_date:"default"`
DateS DateS `json:"date_s"`
}
type DateS struct {
OldData string `json:"old_data" format_date:"default"`
NewDates *NewDates `json:"new_dates"`
}
type NewDates struct {
NewDates string `json:"new_dates" format_date:"default"`
}
func TestNewDateParseTag(t *testing.T) {
u := new(User)
u.Name = "张三"
u.BirthDay = time.Now().String()
t.Logf("user : %v", u)
dp := NewDateParseTag(WithTagName("format_date"))
dp.Parse(u, u)
t.Logf("user new %v", u)
}
// user : &{张三 2022-01-13 16:21:36.2974741 +0800 CST m=+0.003138401 {2022-01-13 16:21:36.3125376 +0800 CST m=+0.018201901 0xc000088550}}
// user new &{张三 2022-01-13 16:21:36 {2022-01-13 16:21:36 0xc000088550}} {2022-01-13 16:21:36 0xc000088550} &{2022-01-13 16:21:36}
func TestDateParseTag_Format2(t *testing.T) {
u := new(User)
u.Name = "张三"
u.BirthDay = time.Now().String()
u.DateS = DateS{
OldData: time.Now().String(),
NewDates: &NewDates{
NewDates: time.Now().String(),
},
}
t.Logf("user : %v", u)
dp := NewDateParseTag(WithTagName("format_date"))
dp.Format(u)
t.Logf("user new %v %v %v", u, u.DateS, u.DateS.NewDates)
}
// user : &{张三 2022-01-13 16:36:50.1955716 +0800 CST m=+0.004237901 {2022-01-13 16:36:50.2103154 +0800 CST m=+0.018981701 0xc000044570}}
// user new &{张三 2022-01-13 16:36:50 {2022-01-13 16:36:50 0xc000044570}} {2022-01-13 16:36:50 0xc000044570} &{2022-01-13 16:36:50}
```

View File

@ -59,7 +59,13 @@ func WithEmptyValue(emptyValue string) Options {
}
type DateParseTag interface {
//Deprecated
Parse(in, out interface{})
// Format 格式化
Format(in interface{})
// ForRange for range data
forRange(field reflect.StructField, val reflect.Value)
}
func NewDateParseTag(opts ...Options) DateParseTag {
@ -90,7 +96,7 @@ func (dp *dateParseTag) check() *dateParseTag {
return dp
}
// @method Parse
// @method Parse Deprecated
// @description: parse time
// @receiver dp
// @param in interface{}
@ -134,6 +140,80 @@ func (dp *dateParseTag) Parse(in, out interface{}) {
return
}
// @method Format
// @description: parse time
// @receiver dp
// @param in interface{}
func (dp *dateParseTag) Format(in interface{}) {
rt := reflect.TypeOf(in).Elem()
rv := reflect.ValueOf(in).Elem()
for i := 0; i < rt.NumField(); i++ {
field := rt.Field(i)
val := rv.Field(i)
dp.forRange(field, val)
}
}
// @method forRange
// @description: for range data
// @param field reflect.StructField
// @param val reflect.Value
func (dp *dateParseTag) forRange(field reflect.StructField, val reflect.Value) {
switch field.Type.Kind() {
case reflect.Ptr:
rt := field.Type.Elem()
rv := val.Elem()
for k := 0; k < rt.NumField(); k++ {
field := rt.Field(k)
val := rv.Field(k)
dp.forRange(field, val)
}
case reflect.Struct:
rt := field.Type
rv := val
for k := 0; k < rt.NumField(); k++ {
field := rt.Field(k)
val := rv.Field(k)
dp.forRange(field, val)
}
case reflect.String:
tag, ok := field.Tag.Lookup(dp.TagName)
if !ok {
return
}
fieldVal := val
if fieldVal.String() == "" || len(fieldVal.String()) <= 0 {
// 校验是否为该空值返回是否为时间类型格式
tFormat, err := validateDateFormat(dp.EmptyValue)
// 如果不是时间类型格式那么直接返回emptyValue的值 反之按照layout格式化返回
if err != nil {
fieldVal.SetString(dp.EmptyValue)
} else {
fieldVal.SetString(parseTime(dp.dateFormatLayout(tFormat), dp.EmptyValue))
}
} else {
fieldVal.SetString(parseTime(dp.dateFormatLayout(tag), fieldVal.String()))
}
}
}
// @method dateFormatLayout
// @description: get date format layout
// @receiver dp

View File

@ -8,6 +8,16 @@ import (
type User struct {
Name string `json:"name"`
BirthDay string `json:"birth_day" format_date:"default"`
DateS DateS `json:"date_s"`
}
type DateS struct {
OldData string `json:"old_data" format_date:"default"`
NewDates *NewDates `json:"new_dates"`
}
type NewDates struct {
NewDates string `json:"new_dates" format_date:"default"`
}
func TestNewDateParseTag(t *testing.T) {
@ -24,3 +34,45 @@ func TestNewDateParseTag(t *testing.T) {
t.Logf("user new %v", u)
}
func TestDateParseTag_Format(t *testing.T) {
u := new(User)
u.Name = "张三"
u.BirthDay = time.Now().String()
u.DateS = DateS{
OldData: time.Now().String(),
NewDates: &NewDates{
NewDates: time.Now().String(),
},
}
t.Logf("user : %v", u)
dp := NewDateParseTag(WithTagName("format_date"))
dp.Format(u)
t.Logf("user new %v %v %v", u, u.DateS, u.DateS.NewDates)
}
func TestDateParseTag_Format2(t *testing.T) {
u := new(User)
u.Name = "张三"
u.BirthDay = time.Now().String()
u.DateS = DateS{
OldData: time.Now().String(),
NewDates: &NewDates{
NewDates: time.Now().String(),
},
}
t.Logf("user : %v", u)
dp := NewDateParseTag(WithTagName("format_date"))
dp.Format(u)
t.Logf("user new %v %v %v", u, u.DateS, u.DateS.NewDates)
}