diff --git a/check.go b/check.go index 4c69d5402..5c73f5498 100644 --- a/check.go +++ b/check.go @@ -3,8 +3,8 @@ package goutil import ( "reflect" + "github.com/gookit/goutil/internal/checkfn" "github.com/gookit/goutil/reflects" - "github.com/gookit/goutil/stdutil" ) // IsNil value check @@ -58,7 +58,7 @@ func IsEqual(src, dst any) bool { // string - check sub-string exists // array,slice - check sub-element exists func Contains(data, elem any) bool { - _, found := stdutil.CheckContains(data, elem) + _, found := checkfn.Contains(data, elem) return found } @@ -70,6 +70,6 @@ func Contains(data, elem any) bool { // string - check sub-string exists // array,slice - check sub-element exists func IsContains(data, elem any) bool { - _, found := stdutil.CheckContains(data, elem) + _, found := checkfn.Contains(data, elem) return found } diff --git a/errorx/panics/assert.go b/errorx/panics/assert.go index d227df020..2971320fe 100644 --- a/errorx/panics/assert.go +++ b/errorx/panics/assert.go @@ -1,8 +1,8 @@ package panics import ( + "github.com/gookit/goutil/internal/checkfn" "github.com/gookit/goutil/internal/comfunc" - "github.com/gookit/goutil/stdutil" ) // IsTrue assert result is true, otherwise will panic @@ -35,14 +35,14 @@ func NotNil(result any, fmtAndArgs ...any) { // IsEmpty assert result is empty, otherwise will panic func IsEmpty(result any, fmtAndArgs ...any) { - if !stdutil.IsEmpty(result) { + if !checkfn.IsEmpty(result) { panicWithMsg("result should be empty", fmtAndArgs) } } // NotEmpty assert result is empty, otherwise will panic func NotEmpty(result any, fmtAndArgs ...any) { - if stdutil.IsEmpty(result) { + if checkfn.IsEmpty(result) { panicWithMsg("result should not be empty", fmtAndArgs) } } diff --git a/internal/TODO.md b/internal/TODO.md new file mode 100644 index 000000000..f58af9823 --- /dev/null +++ b/internal/TODO.md @@ -0,0 +1,6 @@ +# TODO + +## new package + +- misc package 杂项 +- syncs package \ No newline at end of file diff --git a/internal/checkfn/check.go b/internal/checkfn/check.go new file mode 100644 index 000000000..d35b99ac4 --- /dev/null +++ b/internal/checkfn/check.go @@ -0,0 +1,73 @@ +package checkfn + +import ( + "reflect" + "strings" + + "github.com/gookit/goutil/reflects" +) + +// IsNil value check +func IsNil(v any) bool { + if v == nil { + return true + } + return reflects.IsNil(reflect.ValueOf(v)) +} + +// IsEmpty value check +func IsEmpty(v any) bool { + if v == nil { + return true + } + return reflects.IsEmpty(reflect.ValueOf(v)) +} + +// Contains try loop over the data check if the data includes the element. +// +// TIP: only support types: string, map, array, slice +// +// map - check key exists +// string - check sub-string exists +// array,slice - check sub-element exists +// +// return (false, false) if impossible. +// return (true, false) if element was not found. +// return (true, true) if element was found. +func Contains(data, elem any) (valid, found bool) { + dataRv := reflect.ValueOf(data) + dataRt := reflect.TypeOf(data) + if dataRt == nil { + return false, false + } + + dataKind := dataRt.Kind() + + // string + if dataKind == reflect.String { + return true, strings.Contains(dataRv.String(), reflect.ValueOf(elem).String()) + } + + // map + if dataKind == reflect.Map { + mapKeys := dataRv.MapKeys() + for i := 0; i < len(mapKeys); i++ { + if reflects.IsEqual(mapKeys[i].Interface(), elem) { + return true, true + } + } + return true, false + } + + // array, slice - other return false + if dataKind != reflect.Slice && dataKind != reflect.Array { + return false, false + } + + for i := 0; i < dataRv.Len(); i++ { + if reflects.IsEqual(dataRv.Index(i).Interface(), elem) { + return true, true + } + } + return true, false +} diff --git a/internal/comfunc/README.md b/internal/comfunc/README.md new file mode 100644 index 000000000..3057ef9e9 --- /dev/null +++ b/internal/comfunc/README.md @@ -0,0 +1,3 @@ +# common func for internal use + +- don't depend on other external packages \ No newline at end of file diff --git a/syncs/chan.go b/syncs/chan.go new file mode 100644 index 000000000..ac89e8cd7 --- /dev/null +++ b/syncs/chan.go @@ -0,0 +1,35 @@ +package syncs + +import ( + "os" + "os/signal" + "syscall" +) + +// WaitCloseSignals for some huang program. +// +// Usage: +// +// // do something. eg: start a http server +// +// syncs.WaitCloseSignals(func(sig os.Signal) { +// // do something +// }) +func WaitCloseSignals(onClose func(sig os.Signal)) { + signals := make(chan os.Signal, 1) + signal.Notify(signals, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) + + // block until a signal is received. + onClose(<-signals) +} + +// Go is a basic promise implementation: it wraps calls a function in a goroutine +// and returns a channel which will later return the function's return value. +func Go(f func() error) error { + ch := make(chan error) + go func() { + ch <- f() + }() + + return <-ch +} diff --git a/stdutil/chan_test.go b/syncs/chan_test.go similarity index 60% rename from stdutil/chan_test.go rename to syncs/chan_test.go index 4bb7bbf84..619819cce 100644 --- a/stdutil/chan_test.go +++ b/syncs/chan_test.go @@ -1,14 +1,14 @@ -package stdutil_test +package syncs_test import ( "testing" - "github.com/gookit/goutil/stdutil" + "github.com/gookit/goutil/syncs" "github.com/gookit/goutil/testutil/assert" ) func TestGo(t *testing.T) { - err := stdutil.Go(func() error { + err := syncs.Go(func() error { return nil }) assert.NoErr(t, err) diff --git a/stdutil/chan.go b/syncs/signal.go similarity index 65% rename from stdutil/chan.go rename to syncs/signal.go index 084835f71..41f032ce0 100644 --- a/stdutil/chan.go +++ b/syncs/signal.go @@ -1,34 +1,12 @@ -package stdutil +package syncs import ( "context" "fmt" - "io" "os" "os/signal" - "syscall" ) -// WaitCloseSignals for some huang program. -func WaitCloseSignals(closer io.Closer) error { - signals := make(chan os.Signal, 1) - signal.Notify(signals, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT) - <-signals - - return closer.Close() -} - -// Go is a basic promise implementation: it wraps calls a function in a goroutine -// and returns a channel which will later return the function's return value. -func Go(f func() error) error { - ch := make(chan error) - go func() { - ch <- f() - }() - - return <-ch -} - // SignalHandler returns an actor, i.e. an execute and interrupt func, that // terminates with SignalError when the process receives one of the provided // signals, or the parent context is canceled. diff --git a/testutil/assert/asserts.go b/testutil/assert/asserts.go index 741167ead..0b3867b98 100644 --- a/testutil/assert/asserts.go +++ b/testutil/assert/asserts.go @@ -9,15 +9,15 @@ import ( "github.com/gookit/color" "github.com/gookit/goutil/arrutil" + "github.com/gookit/goutil/internal/checkfn" "github.com/gookit/goutil/maputil" "github.com/gookit/goutil/mathutil" "github.com/gookit/goutil/reflects" - "github.com/gookit/goutil/stdutil" ) // Nil asserts that the given is a nil value func Nil(t TestingT, give any, fmtAndArgs ...any) bool { - if stdutil.IsNil(give) { + if checkfn.IsNil(give) { return true } @@ -27,7 +27,7 @@ func Nil(t TestingT, give any, fmtAndArgs ...any) bool { // NotNil asserts that the given is a not nil value func NotNil(t TestingT, give any, fmtAndArgs ...any) bool { - if !stdutil.IsNil(give) { + if !checkfn.IsNil(give) { return true } @@ -175,7 +175,7 @@ func PanicsErrMsg(t TestingT, fn PanicRunFunc, errMsg string, fmtAndArgs ...any) // string - check sub-string exists // array,slice - check sub-element exists func Contains(t TestingT, src, elem any, fmtAndArgs ...any) bool { - valid, found := stdutil.CheckContains(src, elem) + valid, found := checkfn.Contains(src, elem) if valid && found { return true } @@ -199,7 +199,7 @@ func Contains(t TestingT, src, elem any, fmtAndArgs ...any) bool { // string - check sub-string exists // array,slice - check sub-element exists func NotContains(t TestingT, src, elem any, fmtAndArgs ...any) bool { - valid, found := stdutil.CheckContains(src, elem) + valid, found := checkfn.Contains(src, elem) if valid && !found { return true }