- update vendor

master
李光春 1 year ago
parent fdd6dfbc63
commit 50d5b3216c

@ -16,7 +16,7 @@ require (
github.com/go-playground/validator/v10 v10.12.0 github.com/go-playground/validator/v10 v10.12.0
github.com/go-sql-driver/mysql v1.7.0 github.com/go-sql-driver/mysql v1.7.0
github.com/goccy/go-json v0.10.2 github.com/goccy/go-json v0.10.2
github.com/gogf/gf/v2 v2.3.3 github.com/gogf/gf/v2 v2.4.0
github.com/json-iterator/go v1.1.12 github.com/json-iterator/go v1.1.12
github.com/lib/pq v1.10.8 github.com/lib/pq v1.10.8
github.com/mitchellh/mapstructure v1.5.0 github.com/mitchellh/mapstructure v1.5.0

@ -145,8 +145,8 @@ github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogf/gf/v2 v2.3.3 h1:3iry6kybjvuryTtjypG9oUuxrQ0URMT7j0DVg7FFnaw= github.com/gogf/gf/v2 v2.4.0 h1:Tem4xKVI52h92XlKxKTxlID9hzzmTOVSI226vDJRZ1c=
github.com/gogf/gf/v2 v2.3.3/go.mod h1:tsbmtwcAl2chcYoq/fP9W2FZf06aw4i89X34nbSHo9Y= github.com/gogf/gf/v2 v2.4.0/go.mod h1:tsbmtwcAl2chcYoq/fP9W2FZf06aw4i89X34nbSHo9Y=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=

@ -233,13 +233,26 @@ func (a *Array) doRemoveWithoutLock(index int) (value interface{}, found bool) {
// RemoveValue removes an item by value. // RemoveValue removes an item by value.
// It returns true if value is found in the array, or else false if not found. // It returns true if value is found in the array, or else false if not found.
func (a *Array) RemoveValue(value interface{}) bool { func (a *Array) RemoveValue(value interface{}) bool {
if i := a.Search(value); i != -1 { a.mu.Lock()
a.Remove(i) defer a.mu.Unlock()
if i := a.doSearchWithoutLock(value); i != -1 {
a.doRemoveWithoutLock(i)
return true return true
} }
return false return false
} }
// RemoveValues removes multiple items by `values`.
func (a *Array) RemoveValues(values ...interface{}) {
a.mu.Lock()
defer a.mu.Unlock()
for _, value := range values {
if i := a.doSearchWithoutLock(value); i != -1 {
a.doRemoveWithoutLock(i)
}
}
}
// PushLeft pushes one or multiple items to the beginning of array. // PushLeft pushes one or multiple items to the beginning of array.
func (a *Array) PushLeft(value ...interface{}) *Array { func (a *Array) PushLeft(value ...interface{}) *Array {
a.mu.Lock() a.mu.Lock()
@ -487,6 +500,10 @@ func (a *Array) Contains(value interface{}) bool {
func (a *Array) Search(value interface{}) int { func (a *Array) Search(value interface{}) int {
a.mu.RLock() a.mu.RLock()
defer a.mu.RUnlock() defer a.mu.RUnlock()
return a.doSearchWithoutLock(value)
}
func (a *Array) doSearchWithoutLock(value interface{}) int {
if len(a.array) == 0 { if len(a.array) == 0 {
return -1 return -1
} }
@ -778,6 +795,22 @@ func (a *Array) UnmarshalValue(value interface{}) error {
return nil return nil
} }
// Filter iterates array and filters elements using custom callback function.
// It removes the element from array if callback function `filter` returns true,
// it or else does nothing and continues iterating.
func (a *Array) Filter(filter func(index int, value interface{}) bool) *Array {
a.mu.Lock()
defer a.mu.Unlock()
for i := 0; i < len(a.array); {
if filter(i, a.array[i]) {
a.array = append(a.array[:i], a.array[i+1:]...)
} else {
i++
}
}
return a
}
// FilterNil removes all nil value of the array. // FilterNil removes all nil value of the array.
func (a *Array) FilterNil() *Array { func (a *Array) FilterNil() *Array {
a.mu.Lock() a.mu.Lock()

@ -228,13 +228,26 @@ func (a *IntArray) doRemoveWithoutLock(index int) (value int, found bool) {
// RemoveValue removes an item by value. // RemoveValue removes an item by value.
// It returns true if value is found in the array, or else false if not found. // It returns true if value is found in the array, or else false if not found.
func (a *IntArray) RemoveValue(value int) bool { func (a *IntArray) RemoveValue(value int) bool {
if i := a.Search(value); i != -1 { a.mu.Lock()
_, found := a.Remove(i) defer a.mu.Unlock()
return found if i := a.doSearchWithoutLock(value); i != -1 {
a.doRemoveWithoutLock(i)
return true
} }
return false return false
} }
// RemoveValues removes multiple items by `values`.
func (a *IntArray) RemoveValues(values ...int) {
a.mu.Lock()
defer a.mu.Unlock()
for _, value := range values {
if i := a.doSearchWithoutLock(value); i != -1 {
a.doRemoveWithoutLock(i)
}
}
}
// PushLeft pushes one or multiple items to the beginning of array. // PushLeft pushes one or multiple items to the beginning of array.
func (a *IntArray) PushLeft(value ...int) *IntArray { func (a *IntArray) PushLeft(value ...int) *IntArray {
a.mu.Lock() a.mu.Lock()
@ -497,6 +510,10 @@ func (a *IntArray) Contains(value int) bool {
func (a *IntArray) Search(value int) int { func (a *IntArray) Search(value int) int {
a.mu.RLock() a.mu.RLock()
defer a.mu.RUnlock() defer a.mu.RUnlock()
return a.doSearchWithoutLock(value)
}
func (a *IntArray) doSearchWithoutLock(value int) int {
if len(a.array) == 0 { if len(a.array) == 0 {
return -1 return -1
} }
@ -771,6 +788,22 @@ func (a *IntArray) UnmarshalValue(value interface{}) error {
return nil return nil
} }
// Filter iterates array and filters elements using custom callback function.
// It removes the element from array if callback function `filter` returns true,
// it or else does nothing and continues iterating.
func (a *IntArray) Filter(filter func(index int, value int) bool) *IntArray {
a.mu.Lock()
defer a.mu.Unlock()
for i := 0; i < len(a.array); {
if filter(i, a.array[i]) {
a.array = append(a.array[:i], a.array[i+1:]...)
} else {
i++
}
}
return a
}
// FilterEmpty removes all zero value of the array. // FilterEmpty removes all zero value of the array.
func (a *IntArray) FilterEmpty() *IntArray { func (a *IntArray) FilterEmpty() *IntArray {
a.mu.Lock() a.mu.Lock()

@ -222,6 +222,17 @@ func (a *StrArray) RemoveValue(value string) bool {
return false return false
} }
// RemoveValues removes multiple items by `values`.
func (a *StrArray) RemoveValues(values ...string) {
a.mu.Lock()
defer a.mu.Unlock()
for _, value := range values {
if i := a.doSearchWithoutLock(value); i != -1 {
a.doRemoveWithoutLock(i)
}
}
}
// PushLeft pushes one or multiple items to the beginning of array. // PushLeft pushes one or multiple items to the beginning of array.
func (a *StrArray) PushLeft(value ...string) *StrArray { func (a *StrArray) PushLeft(value ...string) *StrArray {
a.mu.Lock() a.mu.Lock()
@ -499,6 +510,10 @@ func (a *StrArray) ContainsI(value string) bool {
func (a *StrArray) Search(value string) int { func (a *StrArray) Search(value string) int {
a.mu.RLock() a.mu.RLock()
defer a.mu.RUnlock() defer a.mu.RUnlock()
return a.doSearchWithoutLock(value)
}
func (a *StrArray) doSearchWithoutLock(value string) int {
if len(a.array) == 0 { if len(a.array) == 0 {
return -1 return -1
} }
@ -784,6 +799,22 @@ func (a *StrArray) UnmarshalValue(value interface{}) error {
return nil return nil
} }
// Filter iterates array and filters elements using custom callback function.
// It removes the element from array if callback function `filter` returns true,
// it or else does nothing and continues iterating.
func (a *StrArray) Filter(filter func(index int, value string) bool) *StrArray {
a.mu.Lock()
defer a.mu.Unlock()
for i := 0; i < len(a.array); {
if filter(i, a.array[i]) {
a.array = append(a.array[:i], a.array[i+1:]...)
} else {
i++
}
}
return a
}
// FilterEmpty removes all empty string value of the array. // FilterEmpty removes all empty string value of the array.
func (a *StrArray) FilterEmpty() *StrArray { func (a *StrArray) FilterEmpty() *StrArray {
a.mu.Lock() a.mu.Lock()

@ -216,6 +216,17 @@ func (a *SortedArray) RemoveValue(value interface{}) bool {
return false return false
} }
// RemoveValues removes an item by `values`.
func (a *SortedArray) RemoveValues(values ...interface{}) {
a.mu.Lock()
defer a.mu.Unlock()
for _, value := range values {
if i, r := a.binSearch(value, false); r == 0 {
a.doRemoveWithoutLock(i)
}
}
}
// PopLeft pops and returns an item from the beginning of array. // PopLeft pops and returns an item from the beginning of array.
// Note that if the array is empty, the `found` is false. // Note that if the array is empty, the `found` is false.
func (a *SortedArray) PopLeft() (value interface{}, found bool) { func (a *SortedArray) PopLeft() (value interface{}, found bool) {
@ -470,7 +481,7 @@ func (a *SortedArray) binSearch(value interface{}, lock bool) (index int, result
// SetUnique sets unique mark to the array, // SetUnique sets unique mark to the array,
// which means it does not contain any repeated items. // which means it does not contain any repeated items.
// It also do unique check, remove all repeated items. // It also does unique check, remove all repeated items.
func (a *SortedArray) SetUnique(unique bool) *SortedArray { func (a *SortedArray) SetUnique(unique bool) *SortedArray {
oldUnique := a.unique oldUnique := a.unique
a.unique = unique a.unique = unique
@ -750,6 +761,22 @@ func (a *SortedArray) FilterNil() *SortedArray {
return a return a
} }
// Filter iterates array and filters elements using custom callback function.
// It removes the element from array if callback function `filter` returns true,
// it or else does nothing and continues iterating.
func (a *SortedArray) Filter(filter func(index int, value interface{}) bool) *SortedArray {
a.mu.Lock()
defer a.mu.Unlock()
for i := 0; i < len(a.array); {
if filter(i, a.array[i]) {
a.array = append(a.array[:i], a.array[i+1:]...)
} else {
i++
}
}
return a
}
// FilterEmpty removes all empty value of the array. // FilterEmpty removes all empty value of the array.
// Values like: 0, nil, false, "", len(slice/map/chan) == 0 are considered empty. // Values like: 0, nil, false, "", len(slice/map/chan) == 0 are considered empty.
func (a *SortedArray) FilterEmpty() *SortedArray { func (a *SortedArray) FilterEmpty() *SortedArray {

@ -202,6 +202,17 @@ func (a *SortedIntArray) RemoveValue(value int) bool {
return false return false
} }
// RemoveValues removes an item by `values`.
func (a *SortedIntArray) RemoveValues(values ...int) {
a.mu.Lock()
defer a.mu.Unlock()
for _, value := range values {
if i, r := a.binSearch(value, false); r == 0 {
a.doRemoveWithoutLock(i)
}
}
}
// PopLeft pops and returns an item from the beginning of array. // PopLeft pops and returns an item from the beginning of array.
// Note that if the array is empty, the `found` is false. // Note that if the array is empty, the `found` is false.
func (a *SortedIntArray) PopLeft() (value int, found bool) { func (a *SortedIntArray) PopLeft() (value int, found bool) {
@ -698,6 +709,22 @@ func (a *SortedIntArray) UnmarshalValue(value interface{}) (err error) {
return err return err
} }
// Filter iterates array and filters elements using custom callback function.
// It removes the element from array if callback function `filter` returns true,
// it or else does nothing and continues iterating.
func (a *SortedIntArray) Filter(filter func(index int, value int) bool) *SortedIntArray {
a.mu.Lock()
defer a.mu.Unlock()
for i := 0; i < len(a.array); {
if filter(i, a.array[i]) {
a.array = append(a.array[:i], a.array[i+1:]...)
} else {
i++
}
}
return a
}
// FilterEmpty removes all zero value of the array. // FilterEmpty removes all zero value of the array.
func (a *SortedIntArray) FilterEmpty() *SortedIntArray { func (a *SortedIntArray) FilterEmpty() *SortedIntArray {
a.mu.Lock() a.mu.Lock()

@ -188,6 +188,17 @@ func (a *SortedStrArray) RemoveValue(value string) bool {
return false return false
} }
// RemoveValues removes an item by `values`.
func (a *SortedStrArray) RemoveValues(values ...string) {
a.mu.Lock()
defer a.mu.Unlock()
for _, value := range values {
if i, r := a.binSearch(value, false); r == 0 {
a.doRemoveWithoutLock(i)
}
}
}
// PopLeft pops and returns an item from the beginning of array. // PopLeft pops and returns an item from the beginning of array.
// Note that if the array is empty, the `found` is false. // Note that if the array is empty, the `found` is false.
func (a *SortedStrArray) PopLeft() (value string, found bool) { func (a *SortedStrArray) PopLeft() (value string, found bool) {
@ -711,6 +722,22 @@ func (a *SortedStrArray) UnmarshalValue(value interface{}) (err error) {
return err return err
} }
// Filter iterates array and filters elements using custom callback function.
// It removes the element from array if callback function `filter` returns true,
// it or else does nothing and continues iterating.
func (a *SortedStrArray) Filter(filter func(index int, value string) bool) *SortedStrArray {
a.mu.Lock()
defer a.mu.Unlock()
for i := 0; i < len(a.array); {
if filter(i, a.array[i]) {
a.array = append(a.array[:i], a.array[i+1:]...)
} else {
i++
}
}
return a
}
// FilterEmpty removes all empty string value of the array. // FilterEmpty removes all empty string value of the array.
func (a *SortedStrArray) FilterEmpty() *SortedStrArray { func (a *SortedStrArray) FilterEmpty() *SortedStrArray {
a.mu.Lock() a.mu.Lock()

@ -27,7 +27,6 @@ import (
// Queue is a concurrent-safe queue built on doubly linked list and channel. // Queue is a concurrent-safe queue built on doubly linked list and channel.
type Queue struct { type Queue struct {
limit int // Limit for queue size. limit int // Limit for queue size.
length *gtype.Int64 // Queue length.
list *glist.List // Underlying list structure for data maintaining. list *glist.List // Underlying list structure for data maintaining.
closed *gtype.Bool // Whether queue is closed. closed *gtype.Bool // Whether queue is closed.
events chan struct{} // Events for data writing. events chan struct{} // Events for data writing.
@ -45,7 +44,6 @@ const (
func New(limit ...int) *Queue { func New(limit ...int) *Queue {
q := &Queue{ q := &Queue{
closed: gtype.NewBool(), closed: gtype.NewBool(),
length: gtype.NewInt64(),
} }
if len(limit) > 0 && limit[0] > 0 { if len(limit) > 0 && limit[0] > 0 {
q.limit = limit[0] q.limit = limit[0]
@ -62,7 +60,6 @@ func New(limit ...int) *Queue {
// Push pushes the data `v` into the queue. // Push pushes the data `v` into the queue.
// Note that it would panic if Push is called after the queue is closed. // Note that it would panic if Push is called after the queue is closed.
func (q *Queue) Push(v interface{}) { func (q *Queue) Push(v interface{}) {
q.length.Add(1)
if q.limit > 0 { if q.limit > 0 {
q.C <- v q.C <- v
} else { } else {
@ -76,9 +73,7 @@ func (q *Queue) Push(v interface{}) {
// Pop pops an item from the queue in FIFO way. // Pop pops an item from the queue in FIFO way.
// Note that it would return nil immediately if Pop is called after the queue is closed. // Note that it would return nil immediately if Pop is called after the queue is closed.
func (q *Queue) Pop() interface{} { func (q *Queue) Pop() interface{} {
item := <-q.C return <-q.C
q.length.Add(-1)
return item
} }
// Close closes the queue. // Close closes the queue.
@ -101,13 +96,18 @@ func (q *Queue) Close() {
} }
// Len returns the length of the queue. // Len returns the length of the queue.
// Note that the result might not be accurate as there's an // Note that the result might not be accurate if using unlimited queue size as there's an
// asynchronous channel reading the list constantly. // asynchronous channel reading the list constantly.
func (q *Queue) Len() (length int64) { func (q *Queue) Len() (length int64) {
return q.length.Val() bufferedSize := int64(len(q.C))
if q.limit > 0 {
return bufferedSize
}
return int64(q.list.Size()) + bufferedSize
} }
// Size is alias of Len. // Size is alias of Len.
// Deprecated: use Len instead.
func (q *Queue) Size() int64 { func (q *Queue) Size() int64 {
return q.Len() return q.Len()
} }
@ -123,14 +123,11 @@ func (q *Queue) asyncLoopFromListToChannel() {
for !q.closed.Val() { for !q.closed.Val() {
<-q.events <-q.events
for !q.closed.Val() { for !q.closed.Val() {
if length := q.list.Len(); length > 0 { if bufferLength := q.list.Len(); bufferLength > 0 {
if length > defaultBatchSize { // When q.C is closed, it will panic here, especially q.C is being blocked for writing.
length = defaultBatchSize // If any error occurs here, it will be caught by recover and be ignored.
} for i := 0; i < bufferLength; i++ {
for _, v := range q.list.PopFronts(length) { q.C <- q.list.PopFront()
// When q.C is closed, it will panic here, especially q.C is being blocked for writing.
// If any error occurs here, it will be caught by recover and be ignored.
q.C <- v
} }
} else { } else {
break break

@ -28,7 +28,7 @@ type Var struct {
// The optional parameter `safe` specifies whether Var is used in concurrent-safety, // The optional parameter `safe` specifies whether Var is used in concurrent-safety,
// which is false in default. // which is false in default.
func New(value interface{}, safe ...bool) *Var { func New(value interface{}, safe ...bool) *Var {
if len(safe) > 0 && !safe[0] { if len(safe) > 0 && safe[0] {
return &Var{ return &Var{
value: gtype.NewInterface(value), value: gtype.NewInterface(value),
safe: true, safe: true,

@ -44,6 +44,7 @@ func init() {
context.Background(), context.Background(),
propagation.MapCarrier(m), propagation.MapCarrier(m),
) )
initCtx = WithCtx(initCtx)
} }
// New creates and returns a context which contains context id. // New creates and returns a context which contains context id.

@ -11,7 +11,6 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime"
"strings" "strings"
"time" "time"
@ -42,16 +41,9 @@ var (
// selfPath is the current running binary path. // selfPath is the current running binary path.
// As it is most commonly used, it is so defined as an internal package variable. // As it is most commonly used, it is so defined as an internal package variable.
selfPath = "" selfPath = ""
// Temporary directory of system.
tempDir = "/tmp"
) )
func init() { func init() {
// Initialize internal package variable: tempDir.
if runtime.GOOS == "windows" || Separator != "/" || !Exists(tempDir) {
tempDir = os.TempDir()
}
// Initialize internal package variable: selfPath. // Initialize internal package variable: selfPath.
selfPath, _ = exec.LookPath(os.Args[0]) selfPath, _ = exec.LookPath(os.Args[0])
if selfPath != "" { if selfPath != "" {
@ -445,14 +437,13 @@ func ExtName(path string) string {
} }
// Temp retrieves and returns the temporary directory of current system. // Temp retrieves and returns the temporary directory of current system.
// It returns "/tmp" is current in *nix system, or else it returns os.TempDir().
// //
// The optional parameter `names` specifies the sub-folders/sub-files, // The optional parameter `names` specifies the sub-folders/sub-files,
// which will be joined with current system separator and returned with the path. // which will be joined with current system separator and returned with the path.
func Temp(names ...string) string { func Temp(names ...string) string {
path := tempDir path := os.TempDir()
for _, name := range names { for _, name := range names {
path += Separator + name path = Join(path, name)
} }
return path return path
} }

@ -42,6 +42,7 @@ type Timer struct {
// TimerOptions is the configuration object for Timer. // TimerOptions is the configuration object for Timer.
type TimerOptions struct { type TimerOptions struct {
Interval time.Duration // Interval is the interval escaped of the timer. Interval time.Duration // Interval is the interval escaped of the timer.
Quick bool // Quick is used for quick timer, which means the timer will not wait for the first interval to be elapsed.
} }
// internalPanic is the custom panic for internal usage. // internalPanic is the custom panic for internal usage.

@ -22,6 +22,9 @@ func New(options ...TimerOptions) *Timer {
} }
if len(options) > 0 { if len(options) > 0 {
t.options = options[0] t.options = options[0]
if t.options.Interval == 0 {
t.options.Interval = defaultInterval
}
} else { } else {
t.options = DefaultOptions() t.options = DefaultOptions()
} }
@ -166,7 +169,8 @@ type createEntryInput struct {
// createEntry creates and adds a timing job to the timer. // createEntry creates and adds a timing job to the timer.
func (t *Timer) createEntry(in createEntryInput) *Entry { func (t *Timer) createEntry(in createEntryInput) *Entry {
var ( var (
infinite = false infinite = false
nextTicks int64
) )
if in.Times <= 0 { if in.Times <= 0 {
infinite = true infinite = true
@ -179,9 +183,15 @@ func (t *Timer) createEntry(in createEntryInput) *Entry {
// then sets it to one tick, which means it will be run in one interval. // then sets it to one tick, which means it will be run in one interval.
intervalTicksOfJob = 1 intervalTicksOfJob = 1
} }
var ( if t.options.Quick {
// If the quick mode is enabled, which means it will be run right now.
// Don't need to wait for the first interval.
nextTicks = t.ticks.Val()
} else {
nextTicks = t.ticks.Val() + intervalTicksOfJob nextTicks = t.ticks.Val() + intervalTicksOfJob
entry = &Entry{ }
var (
entry = &Entry{
job: in.Job, job: in.Job,
ctx: in.Ctx, ctx: in.Ctx,
timer: t, timer: t,

@ -254,22 +254,50 @@ func doConvert(in doConvertInput) (convertedValue interface{}) {
default: default:
if in.ReferValue != nil { if in.ReferValue != nil {
var referReflectValue reflect.Value var (
referReflectValue reflect.Value
)
if v, ok := in.ReferValue.(reflect.Value); ok { if v, ok := in.ReferValue.(reflect.Value); ok {
referReflectValue = v referReflectValue = v
} else { } else {
referReflectValue = reflect.ValueOf(in.ReferValue) referReflectValue = reflect.ValueOf(in.ReferValue)
} }
defer func() { defer func() {
if recover() != nil { if recover() != nil {
in.alreadySetToReferValue = false
if err := bindVarToReflectValue(referReflectValue, in.FromValue, nil); err == nil { if err := bindVarToReflectValue(referReflectValue, in.FromValue, nil); err == nil {
in.alreadySetToReferValue = true in.alreadySetToReferValue = true
convertedValue = referReflectValue.Interface() convertedValue = referReflectValue.Interface()
} }
} }
}() }()
if referReflectValue.Kind() == reflect.Ptr {
// Type converting for custom type pointers.
// Eg:
// type PayMode int
// type Req struct{
// Mode *PayMode
// }
//
// Struct(`{"Mode": 1000}`, &req)
originType := referReflectValue.Type().Elem()
switch originType.Kind() {
case reflect.Struct:
// Not support some kinds.
default:
in.ToTypeName = originType.Kind().String()
in.ReferValue = nil
refElementValue := reflect.ValueOf(doConvert(in))
originTypeValue := reflect.New(refElementValue.Type()).Elem()
originTypeValue.Set(refElementValue)
in.alreadySetToReferValue = true
return originTypeValue.Addr().Convert(referReflectValue.Type()).Interface()
}
}
in.ToTypeName = referReflectValue.Kind().String() in.ToTypeName = referReflectValue.Kind().String()
in.ReferValue = nil in.ReferValue = nil
in.alreadySetToReferValue = true
return reflect.ValueOf(doConvert(in)).Convert(referReflectValue.Type()).Interface() return reflect.ValueOf(doConvert(in)).Convert(referReflectValue.Type()).Interface()
} }
return in.FromValue return in.FromValue

@ -422,6 +422,8 @@ func bindVarToReflectValueWithInterfaceCheck(reflectValue reflect.Value, value i
valueBytes = b valueBytes = b
} else if s, ok := value.(string); ok { } else if s, ok := value.(string); ok {
valueBytes = []byte(s) valueBytes = []byte(s)
} else if f, ok := value.(iString); ok {
valueBytes = []byte(f.String())
} }
if len(valueBytes) > 0 { if len(valueBytes) > 0 {
return v.UnmarshalText(valueBytes), ok return v.UnmarshalText(valueBytes), ok
@ -434,6 +436,8 @@ func bindVarToReflectValueWithInterfaceCheck(reflectValue reflect.Value, value i
valueBytes = b valueBytes = b
} else if s, ok := value.(string); ok { } else if s, ok := value.(string); ok {
valueBytes = []byte(s) valueBytes = []byte(s)
} else if f, ok := value.(iString); ok {
valueBytes = []byte(f.String())
} }
if len(valueBytes) > 0 { if len(valueBytes) > 0 {

@ -45,4 +45,5 @@ const (
GConvShort = "c" // GConv defines the converting target name for specified struct field. GConvShort = "c" // GConv defines the converting target name for specified struct field.
Json = "json" // Json tag is supported by stdlib. Json = "json" // Json tag is supported by stdlib.
Security = "security" // Security defines scheme for authentication. Detail to see https://swagger.io/docs/specification/authentication/ Security = "security" // Security defines scheme for authentication. Detail to see https://swagger.io/docs/specification/authentication/
In = "in" // Swagger distinguishes between the following parameter types based on the parameter location. Detail to see https://swagger.io/docs/specification/describing-parameters/
) )

@ -0,0 +1,28 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gtag
import (
"github.com/gogf/gf/v2/internal/json"
)
var (
// Type name => enums json.
enumsMap = make(map[string]json.RawMessage)
)
// SetGlobalEnums sets the global enums into package.
// Note that this operation is not concurrent safety.
func SetGlobalEnums(enumsJson string) error {
return json.Unmarshal([]byte(enumsJson), &enumsMap)
}
// GetEnumsByType retrieves and returns the stored enums json by type name.
// The type name is like: github.com/gogf/gf/v2/encoding/gjson.ContentType
func GetEnumsByType(typeName string) string {
return string(enumsMap[typeName])
}

@ -108,13 +108,13 @@ func doDump(value interface{}, indent string, buffer *bytes.Buffer, option doDum
} else { } else {
reflectValue = reflect.ValueOf(value) reflectValue = reflect.ValueOf(value)
} }
var reflectKind = reflectValue.Kind()
// Double check nil value. // Double check nil value.
if value == nil { if value == nil || reflectKind == reflect.Invalid {
buffer.WriteString(`<nil>`) buffer.WriteString(`<nil>`)
return return
} }
var ( var (
reflectKind = reflectValue.Kind()
reflectTypeName = reflectValue.Type().String() reflectTypeName = reflectValue.Type().String()
ptrAddress string ptrAddress string
newIndent = indent + dumpIndent newIndent = indent + dumpIndent

@ -117,7 +117,7 @@ github.com/goccy/go-json/internal/encoder/vm_color_indent
github.com/goccy/go-json/internal/encoder/vm_indent github.com/goccy/go-json/internal/encoder/vm_indent
github.com/goccy/go-json/internal/errors github.com/goccy/go-json/internal/errors
github.com/goccy/go-json/internal/runtime github.com/goccy/go-json/internal/runtime
# github.com/gogf/gf/v2 v2.3.3 # github.com/gogf/gf/v2 v2.4.0
## explicit; go 1.15 ## explicit; go 1.15
github.com/gogf/gf/v2/container/garray github.com/gogf/gf/v2/container/garray
github.com/gogf/gf/v2/container/glist github.com/gogf/gf/v2/container/glist

Loading…
Cancel
Save