github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zutil/utils.go (about)

     1  // Package zutil daily development helper functions
     2  package zutil
     3  
     4  import (
     5  	"fmt"
     6  	"os"
     7  	"runtime"
     8  	"strings"
     9  	"time"
    10  )
    11  
    12  type (
    13  	// Stack uintptr array
    14  	Stack []uintptr
    15  	// Nocmp is an uncomparable struct
    16  	Nocmp     [0]func()
    17  	namedArgs struct {
    18  		arg  interface{}
    19  		name string
    20  	}
    21  )
    22  
    23  // Named creates a named argument
    24  func Named(name string, arg interface{}) interface{} {
    25  	return namedArgs{
    26  		name: name,
    27  		arg:  arg,
    28  	}
    29  }
    30  
    31  const (
    32  	maxStackDepth = 1 << 5
    33  )
    34  
    35  // WithRunContext function execution time and memory
    36  func WithRunContext(handler func()) (time.Duration, uint64) {
    37  	start, mem := time.Now(), runtime.MemStats{}
    38  	runtime.ReadMemStats(&mem)
    39  	curMem := mem.Alloc
    40  	handler()
    41  	runtime.ReadMemStats(&mem)
    42  	return time.Since(start), mem.Alloc - curMem
    43  }
    44  
    45  // IfVal Simulate ternary calculations, pay attention to handling no variables or indexing problems
    46  func IfVal(condition bool, trueVal, falseVal interface{}) interface{} {
    47  	if condition {
    48  		return trueVal
    49  	}
    50  	return falseVal
    51  }
    52  
    53  // TryCatch exception capture
    54  func TryCatch(fn func() error) (err error) {
    55  	defer func() {
    56  		if recoverErr := recover(); recoverErr != nil {
    57  			if e, ok := recoverErr.(error); ok {
    58  				err = e
    59  			} else {
    60  				err = fmt.Errorf("%v", recoverErr)
    61  			}
    62  		}
    63  	}()
    64  	err = fn()
    65  	return
    66  }
    67  
    68  // Deprecated: please use zerror.TryCatch
    69  // Try exception capture
    70  func Try(fn func(), catch func(e interface{}), finally ...func()) {
    71  	if len(finally) > 0 {
    72  		defer func() {
    73  			finally[0]()
    74  		}()
    75  	}
    76  	defer func() {
    77  		if err := recover(); err != nil {
    78  			if catch != nil {
    79  				catch(err)
    80  			} else {
    81  				panic(err)
    82  			}
    83  		}
    84  	}()
    85  	fn()
    86  }
    87  
    88  // Deprecated: please use zerror.Panic
    89  // CheckErr Check Err
    90  func CheckErr(err error, exit ...bool) {
    91  	if err != nil {
    92  		if len(exit) > 0 && exit[0] {
    93  			fmt.Println(err)
    94  			os.Exit(1)
    95  			return
    96  		}
    97  		panic(err)
    98  	}
    99  }
   100  
   101  func Callers(skip ...int) Stack {
   102  	var (
   103  		pcs [maxStackDepth]uintptr
   104  		n   = 0
   105  	)
   106  	if len(skip) > 0 {
   107  		n += skip[0]
   108  	}
   109  	return pcs[:runtime.Callers(n, pcs[:])]
   110  }
   111  
   112  func (s Stack) Format(f func(fn *runtime.Func, file string, line int) bool) {
   113  	if s == nil {
   114  		return
   115  	}
   116  	for _, p := range s {
   117  		if fn := runtime.FuncForPC(p - 1); fn != nil {
   118  			file, line := fn.FileLine(p - 1)
   119  			name := fn.Name()
   120  			if !strings.HasSuffix(file, "_test.go") && strings.Contains(name, "github.com/sohaha") {
   121  				continue
   122  			}
   123  			if !f(fn, file, line) {
   124  				break
   125  			}
   126  		}
   127  	}
   128  }