github.com/thlcodes/genfig@v0.3.2-alpha/util/common.go (about)

     1  package util
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"path"
     9  	"reflect"
    10  	"strconv"
    11  	"strings"
    12  	"unsafe"
    13  
    14  	zglob "github.com/mattn/go-zglob"
    15  )
    16  
    17  // ResolveGlobs resolves globs and returns all found files unique
    18  func ResolveGlobs(globs ...string) []string {
    19  	m := map[string]struct{}{}
    20  	for _, glob := range globs {
    21  		found, err := zglob.Glob(glob) // using zglob since filepath.Glob did not work with double star
    22  		if err != nil {
    23  			continue
    24  		}
    25  		for _, f := range found {
    26  			m[f] = struct{}{}
    27  		}
    28  	}
    29  	files := []string{}
    30  	for k := range m {
    31  		if info, _ := os.Stat(k); !info.IsDir() && !strings.HasSuffix(k, ".DS_Store") {
    32  			files = append(files, k)
    33  		}
    34  	}
    35  	return files
    36  }
    37  
    38  // MapString maps an array of strings
    39  func MapString(vs []string, f func(s string) string) []string {
    40  	if len(vs) == 0 || vs == nil {
    41  		return make([]string, 0)
    42  	}
    43  	vsm := make([]string, len(vs))
    44  	for i, v := range vs {
    45  		vsm[i] = f(v)
    46  	}
    47  	return vsm
    48  }
    49  
    50  // ReduceStrings reduces a string array to a string
    51  func ReduceStrings(vs []string, f func(r interface{}, s string) interface{}, r interface{}) interface{} {
    52  	if len(vs) == 0 || vs == nil {
    53  		return r
    54  	}
    55  	for i := range vs {
    56  		r = f(r, vs[i])
    57  	}
    58  	return r
    59  }
    60  
    61  // CleanDir cleans a directory
    62  func CleanDir(name string) error {
    63  	dir, err := ioutil.ReadDir(name)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	for _, d := range dir {
    68  		err := os.RemoveAll(path.Join([]string{name, d.Name()}...))
    69  		if err != nil {
    70  			return err
    71  		}
    72  	}
    73  	return nil
    74  }
    75  
    76  // ReverseStrings reverses an
    77  func ReverseStrings(ss []string) {
    78  	for i := len(ss)/2 - 1; i >= 0; i-- {
    79  		opp := len(ss) - 1 - i
    80  		ss[i], ss[opp] = ss[opp], ss[i]
    81  	}
    82  }
    83  
    84  // ParseString into an interface
    85  func ParseString(s string) interface{} {
    86  	if iv, err := strconv.ParseInt(s, 10, 0); err == nil {
    87  		return iv
    88  	} else if fv, err := strconv.ParseFloat(s, 0); err == nil {
    89  		return fv
    90  	} else if bv, err := strconv.ParseBool(s); err == nil {
    91  		return bv
    92  	} else if ia, ok := ParseArrayString(s); ok {
    93  		return ia
    94  	} else {
    95  		return s
    96  	}
    97  }
    98  
    99  // ParseArrayString parses a string representing an array
   100  func ParseArrayString(s string) ([]interface{}, bool) {
   101  	if !strings.HasPrefix(s, "[") || !strings.HasSuffix(s, "]") {
   102  		return nil, false
   103  	}
   104  	r := []interface{}{}
   105  	if err := json.Unmarshal([]byte(s), &r); err != nil {
   106  		return nil, false
   107  	}
   108  	return r, true
   109  }
   110  
   111  // RecoverError recovers errors
   112  func RecoverError(r interface{}) error {
   113  	switch r.(type) {
   114  	case error:
   115  		return r.(error)
   116  	default:
   117  		return fmt.Errorf("%v", r)
   118  	}
   119  }
   120  
   121  // DetectSliceTypeString returns the actual type of an slice of interfaces
   122  func DetectSliceTypeString(slice []interface{}) string {
   123  	iface := "[]interface {}"
   124  	if len(slice) == 0 {
   125  		return iface
   126  	}
   127  	var typ reflect.Type
   128  	for _, s := range slice {
   129  		t := reflect.TypeOf(s)
   130  		if typ == nil {
   131  			typ = t
   132  			continue
   133  		}
   134  		if t != typ {
   135  			return iface
   136  		}
   137  	}
   138  	return "[]" + typ.String()
   139  }
   140  
   141  // IsInterfaceSlice checks if a given interface is actually a slice of interfaces
   142  func IsInterfaceSlice(i interface{}) (is bool) {
   143  	_, is = i.([]interface{})
   144  	return
   145  }
   146  
   147  // Make64 adds '64' to 'int', 'uint' and 'float'
   148  func Make64(s string) string {
   149  	if strings.HasSuffix(s, "int") || strings.HasSuffix(s, "uint") || strings.HasSuffix(s, "float") {
   150  		return s + "64"
   151  	}
   152  	return s
   153  }
   154  
   155  // B is an unsafe string to bytes
   156  func B(s string) []byte {
   157  	sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
   158  	bh := reflect.SliceHeader{
   159  		Data: sh.Data,
   160  		Len:  sh.Len,
   161  		Cap:  sh.Len,
   162  	}
   163  	return *(*[]byte)(unsafe.Pointer(&bh))
   164  }
   165  
   166  // NoopWriter is a writer that does nothing
   167  type NoopWriter struct{}
   168  
   169  func (NoopWriter) Write(b []byte) (int, error) {
   170  	return len(b), nil
   171  }