github.com/diptanu/nomad@v0.5.7-0.20170516172507-d72e86cbe3d9/helper/funcs.go (about)

     1  package helper
     2  
     3  import (
     4  	"crypto/sha512"
     5  	"fmt"
     6  	"regexp"
     7  	"time"
     8  )
     9  
    10  // validUUID is used to check if a given string looks like a UUID
    11  var validUUID = regexp.MustCompile(`(?i)^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$`)
    12  
    13  // IsUUID returns true if the given string is a valid UUID.
    14  func IsUUID(str string) bool {
    15  	const uuidLen = 36
    16  	if len(str) != uuidLen {
    17  		return false
    18  	}
    19  
    20  	return validUUID.MatchString(str)
    21  }
    22  
    23  // HashUUID takes an input UUID and returns a hashed version of the UUID to
    24  // ensure it is well distributed.
    25  func HashUUID(input string) (output string, hashed bool) {
    26  	if !IsUUID(input) {
    27  		return "", false
    28  	}
    29  
    30  	// Hash the input
    31  	buf := sha512.Sum512([]byte(input))
    32  	output = fmt.Sprintf("%08x-%04x-%04x-%04x-%12x",
    33  		buf[0:4],
    34  		buf[4:6],
    35  		buf[6:8],
    36  		buf[8:10],
    37  		buf[10:16])
    38  
    39  	return output, true
    40  }
    41  
    42  // boolToPtr returns the pointer to a boolean
    43  func BoolToPtr(b bool) *bool {
    44  	return &b
    45  }
    46  
    47  // IntToPtr returns the pointer to an int
    48  func IntToPtr(i int) *int {
    49  	return &i
    50  }
    51  
    52  // UintToPtr returns the pointer to an uint
    53  func Uint64ToPtr(u uint64) *uint64 {
    54  	return &u
    55  }
    56  
    57  // StringToPtr returns the pointer to a string
    58  func StringToPtr(str string) *string {
    59  	return &str
    60  }
    61  
    62  // TimeToPtr returns the pointer to a time stamp
    63  func TimeToPtr(t time.Duration) *time.Duration {
    64  	return &t
    65  }
    66  
    67  // MapStringStringSliceValueSet returns the set of values in a map[string][]string
    68  func MapStringStringSliceValueSet(m map[string][]string) []string {
    69  	set := make(map[string]struct{})
    70  	for _, slice := range m {
    71  		for _, v := range slice {
    72  			set[v] = struct{}{}
    73  		}
    74  	}
    75  
    76  	flat := make([]string, 0, len(set))
    77  	for k := range set {
    78  		flat = append(flat, k)
    79  	}
    80  	return flat
    81  }
    82  
    83  func SliceStringToSet(s []string) map[string]struct{} {
    84  	m := make(map[string]struct{}, (len(s)+1)/2)
    85  	for _, k := range s {
    86  		m[k] = struct{}{}
    87  	}
    88  	return m
    89  }
    90  
    91  // SliceStringIsSubset returns whether the smaller set of strings is a subset of
    92  // the larger. If the smaller slice is not a subset, the offending elements are
    93  // returned.
    94  func SliceStringIsSubset(larger, smaller []string) (bool, []string) {
    95  	largerSet := make(map[string]struct{}, len(larger))
    96  	for _, l := range larger {
    97  		largerSet[l] = struct{}{}
    98  	}
    99  
   100  	subset := true
   101  	var offending []string
   102  	for _, s := range smaller {
   103  		if _, ok := largerSet[s]; !ok {
   104  			subset = false
   105  			offending = append(offending, s)
   106  		}
   107  	}
   108  
   109  	return subset, offending
   110  }
   111  
   112  func SliceSetDisjoint(first, second []string) (bool, []string) {
   113  	contained := make(map[string]struct{}, len(first))
   114  	for _, k := range first {
   115  		contained[k] = struct{}{}
   116  	}
   117  
   118  	offending := make(map[string]struct{})
   119  	for _, k := range second {
   120  		if _, ok := contained[k]; ok {
   121  			offending[k] = struct{}{}
   122  		}
   123  	}
   124  
   125  	if len(offending) == 0 {
   126  		return true, nil
   127  	}
   128  
   129  	flattened := make([]string, 0, len(offending))
   130  	for k := range offending {
   131  		flattened = append(flattened, k)
   132  	}
   133  	return false, flattened
   134  }
   135  
   136  // Helpers for copying generic structures.
   137  func CopyMapStringString(m map[string]string) map[string]string {
   138  	l := len(m)
   139  	if l == 0 {
   140  		return nil
   141  	}
   142  
   143  	c := make(map[string]string, l)
   144  	for k, v := range m {
   145  		c[k] = v
   146  	}
   147  	return c
   148  }
   149  
   150  func CopyMapStringInt(m map[string]int) map[string]int {
   151  	l := len(m)
   152  	if l == 0 {
   153  		return nil
   154  	}
   155  
   156  	c := make(map[string]int, l)
   157  	for k, v := range m {
   158  		c[k] = v
   159  	}
   160  	return c
   161  }
   162  
   163  func CopyMapStringFloat64(m map[string]float64) map[string]float64 {
   164  	l := len(m)
   165  	if l == 0 {
   166  		return nil
   167  	}
   168  
   169  	c := make(map[string]float64, l)
   170  	for k, v := range m {
   171  		c[k] = v
   172  	}
   173  	return c
   174  }
   175  
   176  func CopySliceString(s []string) []string {
   177  	l := len(s)
   178  	if l == 0 {
   179  		return nil
   180  	}
   181  
   182  	c := make([]string, l)
   183  	for i, v := range s {
   184  		c[i] = v
   185  	}
   186  	return c
   187  }
   188  
   189  func CopySliceInt(s []int) []int {
   190  	l := len(s)
   191  	if l == 0 {
   192  		return nil
   193  	}
   194  
   195  	c := make([]int, l)
   196  	for i, v := range s {
   197  		c[i] = v
   198  	}
   199  	return c
   200  }
   201  
   202  // CleanEnvVar replaces all occurrences of illegal characters in an environment
   203  // variable with the specified byte.
   204  func CleanEnvVar(s string, r byte) string {
   205  	b := []byte(s)
   206  	for i, c := range b {
   207  		switch {
   208  		case c == '_':
   209  		case c >= 'a' && c <= 'z':
   210  		case c >= 'A' && c <= 'Z':
   211  		case i > 0 && c >= '0' && c <= '9':
   212  		default:
   213  			// Replace!
   214  			b[i] = r
   215  		}
   216  	}
   217  	return string(b)
   218  }