github.com/blend/go-sdk@v1.20220411.3/stringutil/runeset.go (about)

     1  /*
     2  
     3  Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package stringutil
     9  
    10  import "sort"
    11  
    12  var (
    13  	// LowerLetters is a runset of lowercase letters.
    14  	LowerLetters Runeset = []rune("abcdefghijklmnopqrstuvwxyz")
    15  
    16  	// UpperLetters is a runset of uppercase letters.
    17  	UpperLetters Runeset = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    18  
    19  	// Letters is a runset of both lower and uppercase letters.
    20  	Letters = append(LowerLetters, UpperLetters...)
    21  
    22  	// Numbers is a runset of numeric characters.
    23  	Numbers Runeset = []rune("0123456789")
    24  
    25  	// LettersAndNumbers is a runset of letters and numeric characters.
    26  	LettersAndNumbers = append(Letters, Numbers...)
    27  
    28  	// Symbols is a runset of symbol characters.
    29  	Symbols Runeset = []rune(`!@#$%^&*()_+-=[]{}\|:;`)
    30  
    31  	// LettersNumbersAndSymbols is a runset of letters, numbers and symbols.
    32  	LettersNumbersAndSymbols = append(LettersAndNumbers, Symbols...)
    33  )
    34  
    35  // CombineRunsets combines given runsets into a single runset.
    36  func CombineRunsets(runesets ...[]rune) []rune {
    37  	output := []rune{}
    38  	for _, set := range runesets {
    39  		output = append(output, set...)
    40  	}
    41  	return output
    42  }
    43  
    44  // Runeset is a set of runes
    45  type Runeset []rune
    46  
    47  // Len implements part of sorter.
    48  func (rs Runeset) Len() int {
    49  	return len(rs)
    50  }
    51  
    52  // Swap implements part of sorter.
    53  func (rs Runeset) Swap(i, j int) {
    54  	rs[i], rs[j] = rs[j], rs[i]
    55  }
    56  
    57  // Less implements part of sorter.
    58  func (rs Runeset) Less(i, j int) bool {
    59  	return uint16(rs[i]) < uint16(rs[j])
    60  }
    61  
    62  // Set returns a map of the runes in the set.
    63  func (rs Runeset) Set() map[rune]bool {
    64  	seen := make(map[rune]bool)
    65  	for _, r := range rs {
    66  		seen[r] = true
    67  	}
    68  	return seen
    69  }
    70  
    71  // Combine merges runesets.
    72  func (rs Runeset) Combine(other ...Runeset) Runeset {
    73  	seen := rs.Set()
    74  	for _, set := range other {
    75  		for r := range set.Set() {
    76  			seen[r] = true
    77  		}
    78  	}
    79  
    80  	var output []rune
    81  	for r := range seen {
    82  		output = append(output, r)
    83  	}
    84  
    85  	sort.Sort(Runeset(output))
    86  	return Runeset(output)
    87  }
    88  
    89  // Random returns a random selection of runes from the set.
    90  func (rs Runeset) Random(length int) string {
    91  	runes := make([]rune, length)
    92  	for index := range runes {
    93  		runes[index] = rs[provider.Intn(len(rs)-1)]
    94  	}
    95  	return string(runes)
    96  }