Switch remote deploy to vendored source builds
Move remote deployment to a vendored source bundle built on the target host via Docker so redeploys no longer require local cross-compilation or host Go installation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
21
vendor/github.com/leaanthony/go-ansi-parser/LICENSE
generated
vendored
Normal file
21
vendor/github.com/leaanthony/go-ansi-parser/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021-Present Lea Anthony
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
86
vendor/github.com/leaanthony/go-ansi-parser/README.md
generated
vendored
Normal file
86
vendor/github.com/leaanthony/go-ansi-parser/README.md
generated
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
<p align="center" style="text-align: center">
|
||||
<img src="logo.png"><br/>
|
||||
</p>
|
||||
<p align="center">
|
||||
A library for parsing ANSI encoded strings<br/><br/>
|
||||
<a href="https://github.com/leaanthony/go-ansi-parser/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg"></a>
|
||||
<a href="https://goreportcard.com/report/github.com/leaanthony/go-ansi-parser"><img src="https://goreportcard.com/badge/github.com/leaanthony/go-ansi-parser"/></a>
|
||||
<a href="http://godoc.org/github.com/leaanthony/go-ansi-parser"><img src="https://img.shields.io/badge/godoc-reference-blue.svg"/></a>
|
||||
<a href="https://github.com/leaanthony/go-ansi-parser/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" /></a>
|
||||
<a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fleaanthony%2Fgo-ansi-parser?ref=badge_shield" alt="FOSSA Status"><img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fleaanthony%2Fgo-ansi-parser.svg?type=shield"/></a>
|
||||
</p>
|
||||
|
||||
Go ANSI Parser converts strings with [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)
|
||||
into a slice of structs that represent styled text. Features:
|
||||
|
||||
* Can parse ANSI 16, 256 and TrueColor
|
||||
* Supports all styles: Regular, Bold, Faint, Italic, Blinking, Inversed, Invisible, Underlined, Strikethrough
|
||||
* Provides RGB, Hex, HSL, ANSI ID and Name for parsed colours
|
||||
* Truncation - works with emojis and grapheme clusters
|
||||
* Length - works with emojis and grapheme clusters
|
||||
* Cleanse - removes the ansi escape codes
|
||||
* Configurable colour map for customisation
|
||||
* 100% Test Coverage
|
||||
|
||||
# Installation
|
||||
```shell
|
||||
go get github.com/leaanthony/go-ansi-parser
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Parse
|
||||
```go
|
||||
text, err := ansi.Parse("\u001b[1;31;40mHello World\033[0m")
|
||||
|
||||
// is the equivalent of...
|
||||
|
||||
text := []*ansi.StyledText{
|
||||
{
|
||||
Label: "Hello World",
|
||||
FgCol: &ansi.Col{
|
||||
Id: 9,
|
||||
Hex: "#ff0000",
|
||||
Rgb: &ansi.Rgb{ R: 255, G: 0, B: 0 },
|
||||
Hsl: &ansi.Hsl{ H: 0, S: 100, L: 50 },
|
||||
Name: "Red",
|
||||
},
|
||||
BgCol: &ansi.Col{
|
||||
Id: 0,
|
||||
Hex: "#000000",
|
||||
Rgb: &ansi.Rgb{0, 0, 0},
|
||||
Hsl: &ansi.Hsl{0, 0, 0},
|
||||
Name: "Black",
|
||||
},
|
||||
Style: 1,
|
||||
},
|
||||
}
|
||||
```
|
||||
### Truncating
|
||||
```go
|
||||
shorter, err := ansi.Truncate("\u001b[1;31;40mHello\033[0m \u001b[0;30mWorld!\033[0m", 8)
|
||||
|
||||
// is the equivalent of...
|
||||
|
||||
shorter := "\u001b[1;31;40mHello\033[0m \u001b[0;30mWo\033[0m"
|
||||
```
|
||||
### Cleanse
|
||||
```go
|
||||
cleaner, err := ansi.Cleanse("\u001b[1;31;40mHello\033[0m \u001b[0;30mWorld!\033[0m")
|
||||
|
||||
// is the equivalent of...
|
||||
|
||||
cleaner := "Hello World!"
|
||||
```
|
||||
### Length
|
||||
```go
|
||||
length, err := ansi.Length("\u001b[1;31;40mHello\033[0m \u001b[0;30mWorld!\033[0m")
|
||||
|
||||
// is the equivalent of...
|
||||
|
||||
length := 12
|
||||
|
||||
// Works with grapheme clusters and emoji
|
||||
length, err := ansi.Length("\u001b[1;31;40m👩🏽🔧😎\033[0m") // 2
|
||||
```
|
||||
557
vendor/github.com/leaanthony/go-ansi-parser/ansi.go
generated
vendored
Normal file
557
vendor/github.com/leaanthony/go-ansi-parser/ansi.go
generated
vendored
Normal file
@@ -0,0 +1,557 @@
|
||||
package ansi
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/rivo/uniseg"
|
||||
)
|
||||
|
||||
// TextStyle is a type representing the
|
||||
// ansi text styles
|
||||
type TextStyle int
|
||||
|
||||
const (
|
||||
// Bold Style
|
||||
Bold TextStyle = 1 << 0
|
||||
// Faint Style
|
||||
Faint TextStyle = 1 << 1
|
||||
// Italic Style
|
||||
Italic TextStyle = 1 << 2
|
||||
// Blinking Style
|
||||
Blinking TextStyle = 1 << 3
|
||||
// Inversed Style
|
||||
Inversed TextStyle = 1 << 4
|
||||
// Invisible Style
|
||||
Invisible TextStyle = 1 << 5
|
||||
// Underlined Style
|
||||
Underlined TextStyle = 1 << 6
|
||||
// Strikethrough Style
|
||||
Strikethrough TextStyle = 1 << 7
|
||||
// Bright Style
|
||||
Bright TextStyle = 1 << 8
|
||||
)
|
||||
|
||||
type ColourMode int
|
||||
|
||||
const (
|
||||
Default ColourMode = 0
|
||||
TwoFiveSix ColourMode = 1
|
||||
TrueColour ColourMode = 2
|
||||
)
|
||||
|
||||
var invalid = fmt.Errorf("invalid ansi string")
|
||||
var missingTerminator = fmt.Errorf("missing escape terminator 'm'")
|
||||
var invalidTrueColorSequence = fmt.Errorf("invalid TrueColor sequence")
|
||||
var invalid256ColSequence = fmt.Errorf("invalid 256 colour sequence")
|
||||
|
||||
const (
|
||||
// Default colors uses foreground color codes [30-37].
|
||||
// See ColourMap and case for background colors.
|
||||
defaultForegroundColor = "37"
|
||||
defaultBackgroundColor = "30"
|
||||
)
|
||||
|
||||
// StyledText represents a single formatted string
|
||||
type StyledText struct {
|
||||
Label string
|
||||
FgCol *Col
|
||||
BgCol *Col
|
||||
Style TextStyle
|
||||
ColourMode ColourMode
|
||||
// Offset is the offset into the input string where the StyledText begins
|
||||
Offset int
|
||||
// Len is the length in bytes of the substring of the input text that
|
||||
// contains the styled text
|
||||
Len int
|
||||
}
|
||||
|
||||
func (s *StyledText) styleToParams() []string {
|
||||
var params []string
|
||||
if s.Bold() {
|
||||
params = append(params, "1")
|
||||
}
|
||||
if s.Faint() {
|
||||
params = append(params, "2")
|
||||
}
|
||||
if s.Italic() {
|
||||
params = append(params, "3")
|
||||
}
|
||||
if s.Underlined() {
|
||||
params = append(params, "4")
|
||||
}
|
||||
if s.Blinking() {
|
||||
params = append(params, "5")
|
||||
}
|
||||
if s.Inversed() {
|
||||
params = append(params, "7")
|
||||
}
|
||||
if s.Invisible() {
|
||||
params = append(params, "8")
|
||||
}
|
||||
if s.Strikethrough() {
|
||||
params = append(params, "9")
|
||||
}
|
||||
if s.FgCol != nil {
|
||||
// Do we have an ID?
|
||||
switch s.ColourMode {
|
||||
case Default:
|
||||
offset := 30
|
||||
id := s.FgCol.Id
|
||||
// Adjust when bold has been applied to the id
|
||||
if (s.Bold() || s.Bright()) && id > 7 && id < 16 {
|
||||
id -= 8
|
||||
}
|
||||
if s.Bright() {
|
||||
offset = 90
|
||||
}
|
||||
params = append(params, fmt.Sprintf("%d", id+offset))
|
||||
case TwoFiveSix:
|
||||
params = append(params, []string{"38", "5", fmt.Sprintf("%d", s.FgCol.Id)}...)
|
||||
case TrueColour:
|
||||
r := fmt.Sprintf("%d", s.FgCol.Rgb.R)
|
||||
g := fmt.Sprintf("%d", s.FgCol.Rgb.G)
|
||||
b := fmt.Sprintf("%d", s.FgCol.Rgb.B)
|
||||
params = append(params, []string{"38", "2", r, g, b}...)
|
||||
}
|
||||
}
|
||||
if s.BgCol != nil {
|
||||
// Do we have an ID?
|
||||
switch s.ColourMode {
|
||||
case Default:
|
||||
id := s.BgCol.Id
|
||||
offset := 40
|
||||
if s.Bright() {
|
||||
offset = 100
|
||||
}
|
||||
// Adjust when bold has been applied to the id
|
||||
if (s.Bold() || s.Bright()) && id > 7 && id < 16 {
|
||||
id -= 8
|
||||
}
|
||||
params = append(params, fmt.Sprintf("%d", id+offset))
|
||||
case TwoFiveSix:
|
||||
params = append(params, []string{"48", "5", fmt.Sprintf("%d", s.BgCol.Id)}...)
|
||||
case TrueColour:
|
||||
r := fmt.Sprintf("%d", s.BgCol.Rgb.R)
|
||||
g := fmt.Sprintf("%d", s.BgCol.Rgb.G)
|
||||
b := fmt.Sprintf("%d", s.BgCol.Rgb.B)
|
||||
params = append(params, []string{"48", "2", r, g, b}...)
|
||||
}
|
||||
}
|
||||
return params
|
||||
}
|
||||
|
||||
func (s *StyledText) String() string {
|
||||
params := strings.Join(s.styleToParams(), ";")
|
||||
return "\033[0;" + params + "m" + s.Label + "\033[0m"
|
||||
}
|
||||
|
||||
// Bold will return true if the text has a Bold style
|
||||
func (s *StyledText) Bold() bool {
|
||||
return s.Style&Bold == Bold
|
||||
}
|
||||
|
||||
// Faint will return true if the text has a Faint style
|
||||
func (s *StyledText) Faint() bool {
|
||||
return s.Style&Faint == Faint
|
||||
}
|
||||
|
||||
// Italic will return true if the text has an Italic style
|
||||
func (s *StyledText) Italic() bool {
|
||||
return s.Style&Italic == Italic
|
||||
}
|
||||
|
||||
// Blinking will return true if the text has a Blinking style
|
||||
func (s *StyledText) Blinking() bool {
|
||||
return s.Style&Blinking == Blinking
|
||||
}
|
||||
|
||||
// Inversed will return true if the text has an Inversed style
|
||||
func (s *StyledText) Inversed() bool {
|
||||
return s.Style&Inversed == Inversed
|
||||
}
|
||||
|
||||
// Invisible will return true if the text has an Invisible style
|
||||
func (s *StyledText) Invisible() bool {
|
||||
return s.Style&Invisible == Invisible
|
||||
}
|
||||
|
||||
// Underlined will return true if the text has an Underlined style
|
||||
func (s *StyledText) Underlined() bool {
|
||||
return s.Style&Underlined == Underlined
|
||||
}
|
||||
|
||||
// Strikethrough will return true if the text has a Strikethrough style
|
||||
func (s *StyledText) Strikethrough() bool {
|
||||
return s.Style&Strikethrough == Strikethrough
|
||||
}
|
||||
|
||||
// Bright will return true if the text has a Bright style
|
||||
func (s *StyledText) Bright() bool {
|
||||
return s.Style&Bright == Bright
|
||||
}
|
||||
|
||||
// ColourMap maps ansi identifiers to a colour
|
||||
var ColourMap = map[string]map[string]*Col{
|
||||
"Regular": {
|
||||
"30": Cols[0],
|
||||
"31": Cols[1],
|
||||
"32": Cols[2],
|
||||
"33": Cols[3],
|
||||
"34": Cols[4],
|
||||
"35": Cols[5],
|
||||
"36": Cols[6],
|
||||
"37": Cols[7],
|
||||
"90": Cols[8],
|
||||
"91": Cols[9],
|
||||
"92": Cols[10],
|
||||
"93": Cols[11],
|
||||
"94": Cols[12],
|
||||
"95": Cols[13],
|
||||
"96": Cols[14],
|
||||
"97": Cols[15],
|
||||
"100": Cols[8],
|
||||
"101": Cols[9],
|
||||
"102": Cols[10],
|
||||
"103": Cols[11],
|
||||
"104": Cols[12],
|
||||
"105": Cols[13],
|
||||
"106": Cols[14],
|
||||
"107": Cols[15],
|
||||
},
|
||||
"Bold": {
|
||||
"30": Cols[8],
|
||||
"31": Cols[9],
|
||||
"32": Cols[10],
|
||||
"33": Cols[11],
|
||||
"34": Cols[12],
|
||||
"35": Cols[13],
|
||||
"36": Cols[14],
|
||||
"37": Cols[15],
|
||||
"90": Cols[8],
|
||||
"91": Cols[9],
|
||||
"92": Cols[10],
|
||||
"93": Cols[11],
|
||||
"94": Cols[12],
|
||||
"95": Cols[13],
|
||||
"96": Cols[14],
|
||||
"97": Cols[15],
|
||||
"100": Cols[8],
|
||||
"101": Cols[9],
|
||||
"102": Cols[10],
|
||||
"103": Cols[11],
|
||||
"104": Cols[12],
|
||||
"105": Cols[13],
|
||||
"106": Cols[14],
|
||||
"107": Cols[15],
|
||||
},
|
||||
"Faint": {
|
||||
"30": Cols[0],
|
||||
"31": Cols[1],
|
||||
"32": Cols[2],
|
||||
"33": Cols[3],
|
||||
"34": Cols[4],
|
||||
"35": Cols[5],
|
||||
"36": Cols[6],
|
||||
"37": Cols[7],
|
||||
},
|
||||
}
|
||||
|
||||
// Parse will convert an ansi encoded string and return
|
||||
// a slice of StyledText structs that represent the text.
|
||||
// If parsing is unsuccessful, an error is returned.
|
||||
func Parse(input string, options ...ParseOption) ([]*StyledText, error) {
|
||||
var result []*StyledText
|
||||
index := 0
|
||||
offset := 0
|
||||
escapeCodeLen := 0
|
||||
var currentStyledText = &StyledText{}
|
||||
|
||||
if len(input) == 0 {
|
||||
return []*StyledText{currentStyledText}, nil
|
||||
}
|
||||
|
||||
for {
|
||||
// Read all chars to next escape code
|
||||
esc := strings.Index(input, "\033[")
|
||||
|
||||
// If no more esc chars, save what's left and return
|
||||
if esc == -1 {
|
||||
text := input[index:]
|
||||
if len(text) > 0 {
|
||||
currentStyledText.Label = text
|
||||
currentStyledText.Offset = offset
|
||||
currentStyledText.Len = len(text) + escapeCodeLen
|
||||
result = append(result, currentStyledText)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
label := input[:esc]
|
||||
if len(label) > 0 {
|
||||
currentStyledText.Label = label
|
||||
currentStyledText.Offset = offset
|
||||
currentStyledText.Len = len(label) + escapeCodeLen
|
||||
offset += currentStyledText.Len
|
||||
result = append(result, currentStyledText)
|
||||
currentStyledText = &StyledText{
|
||||
Label: "",
|
||||
FgCol: currentStyledText.FgCol,
|
||||
BgCol: currentStyledText.BgCol,
|
||||
Style: currentStyledText.Style,
|
||||
}
|
||||
escapeCodeLen = 0
|
||||
}
|
||||
input = input[esc:]
|
||||
// skip
|
||||
input = input[2:]
|
||||
|
||||
// Read in params
|
||||
endesc := strings.Index(input, "m")
|
||||
if endesc == -1 {
|
||||
return nil, missingTerminator
|
||||
}
|
||||
paramText := input[:endesc]
|
||||
input = input[endesc+1:]
|
||||
escapeCodeLen += 2 + endesc + 1
|
||||
params := strings.Split(paramText, ";")
|
||||
colourMap := ColourMap["Regular"]
|
||||
skip := 0
|
||||
for index, param := range params {
|
||||
if skip > 0 {
|
||||
skip--
|
||||
continue
|
||||
}
|
||||
param = stripLeadingZeros(param)
|
||||
switch param {
|
||||
case "0", "":
|
||||
colourMap = ColourMap["Regular"]
|
||||
currentStyledText.Style = 0
|
||||
currentStyledText.FgCol = nil
|
||||
currentStyledText.BgCol = nil
|
||||
case "1":
|
||||
// Bold
|
||||
colourMap = ColourMap["Bold"]
|
||||
currentStyledText.Style |= Bold
|
||||
case "2":
|
||||
// Dim/Feint
|
||||
colourMap = ColourMap["Faint"]
|
||||
currentStyledText.Style |= Faint
|
||||
case "3":
|
||||
// Italic
|
||||
currentStyledText.Style |= Italic
|
||||
case "4":
|
||||
// Underlined
|
||||
currentStyledText.Style |= Underlined
|
||||
case "5":
|
||||
// Blinking
|
||||
currentStyledText.Style |= Blinking
|
||||
case "7":
|
||||
// Inversed
|
||||
currentStyledText.Style |= Inversed
|
||||
case "8":
|
||||
// Invisible
|
||||
currentStyledText.Style |= Invisible
|
||||
case "9":
|
||||
// Strikethrough
|
||||
currentStyledText.Style |= Strikethrough
|
||||
case "30", "31", "32", "33", "34", "35", "36", "37":
|
||||
currentStyledText.FgCol = colourMap[param]
|
||||
case "90", "91", "92", "93", "94", "95", "96", "97":
|
||||
currentStyledText.FgCol = colourMap[param]
|
||||
currentStyledText.Style |= Bright
|
||||
case "100", "101", "102", "103", "104", "105", "106", "107":
|
||||
currentStyledText.BgCol = colourMap[param]
|
||||
currentStyledText.Style |= Bright
|
||||
case "40", "41", "42", "43", "44", "45", "46", "47":
|
||||
bgcol := "3" + param[1:] // Equivalent of -10
|
||||
currentStyledText.BgCol = colourMap[bgcol]
|
||||
case "38", "48":
|
||||
if len(params)-index < 3 {
|
||||
return nil, invalid
|
||||
}
|
||||
// 256 colours
|
||||
param1 := stripLeadingZeros(params[index+1])
|
||||
if param1 == "5" {
|
||||
skip = 2
|
||||
colIndexText := stripLeadingZeros(params[index+2])
|
||||
colIndex, err := strconv.Atoi(colIndexText)
|
||||
if err != nil {
|
||||
return nil, invalid256ColSequence
|
||||
}
|
||||
if colIndex < 0 || colIndex > 255 {
|
||||
return nil, invalid256ColSequence
|
||||
}
|
||||
currentStyledText.ColourMode = TwoFiveSix
|
||||
if param == "38" {
|
||||
currentStyledText.FgCol = Cols[colIndex]
|
||||
continue
|
||||
}
|
||||
currentStyledText.BgCol = Cols[colIndex]
|
||||
continue
|
||||
}
|
||||
// we must have 4 params left
|
||||
if len(params)-index < 5 {
|
||||
return nil, invalidTrueColorSequence
|
||||
}
|
||||
if param1 != "2" {
|
||||
return nil, invalidTrueColorSequence
|
||||
}
|
||||
var r, g, b uint8
|
||||
ri, err := strconv.Atoi(params[index+2])
|
||||
if err != nil {
|
||||
return nil, invalidTrueColorSequence
|
||||
}
|
||||
gi, err := strconv.Atoi(params[index+3])
|
||||
if err != nil {
|
||||
return nil, invalidTrueColorSequence
|
||||
}
|
||||
bi, err := strconv.Atoi(params[index+4])
|
||||
if err != nil {
|
||||
return nil, invalidTrueColorSequence
|
||||
}
|
||||
if bi > 255 || gi > 255 || ri > 255 {
|
||||
return nil, invalidTrueColorSequence
|
||||
}
|
||||
if bi < 0 || gi < 0 || ri < 0 {
|
||||
return nil, invalidTrueColorSequence
|
||||
}
|
||||
r = uint8(ri)
|
||||
g = uint8(gi)
|
||||
b = uint8(bi)
|
||||
skip = 4
|
||||
colvalue := fmt.Sprintf("#%02x%02x%02x", r, g, b)
|
||||
currentStyledText.ColourMode = TrueColour
|
||||
if param == "38" {
|
||||
currentStyledText.FgCol = &Col{Id: 256, Hex: colvalue, Rgb: Rgb{r, g, b}}
|
||||
continue
|
||||
}
|
||||
currentStyledText.BgCol = &Col{Id: 256, Hex: colvalue, Rgb: Rgb{r, g, b}}
|
||||
case "39":
|
||||
// Lookup for default foreground color.
|
||||
foregroundColor := colourMap[defaultForegroundColor]
|
||||
for _, option := range options {
|
||||
if option.ansiForegroundColor != "" {
|
||||
foregroundColor = colourMap[option.ansiForegroundColor]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Set selected foreground color.
|
||||
currentStyledText.FgCol = foregroundColor
|
||||
case "49":
|
||||
// Lookup for default background color.
|
||||
backgroundColor := colourMap[defaultBackgroundColor]
|
||||
for _, option := range options {
|
||||
if option.ansiBackgroundColor != "" {
|
||||
backgroundColor = colourMap[option.ansiBackgroundColor]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Set selected background color.
|
||||
currentStyledText.BgCol = backgroundColor
|
||||
default:
|
||||
// Unexpected codes may be ignored.
|
||||
unexpectedCodeIgnored := false
|
||||
for _, option := range options {
|
||||
if option.ignoreUnexpectedCode {
|
||||
unexpectedCodeIgnored = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !unexpectedCodeIgnored {
|
||||
return nil, invalid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func stripLeadingZeros(s string) string {
|
||||
if len(s) < 2 {
|
||||
return s
|
||||
}
|
||||
return strings.TrimLeft(s, "0")
|
||||
}
|
||||
|
||||
// HasEscapeCodes tests that input has escape codes.
|
||||
func HasEscapeCodes(input string) bool {
|
||||
return strings.IndexAny(input, "\033[") != -1
|
||||
}
|
||||
|
||||
// String builds an ANSI string for specified StyledText slice.
|
||||
func String(input []*StyledText) string {
|
||||
var result strings.Builder
|
||||
for _, text := range input {
|
||||
params := text.styleToParams()
|
||||
if len(params) == 0 {
|
||||
result.WriteString(text.Label)
|
||||
continue
|
||||
}
|
||||
result.WriteString(text.String())
|
||||
}
|
||||
return result.String()
|
||||
}
|
||||
|
||||
// Truncate truncates text to length but preserves control symbols in ANSI string.
|
||||
func Truncate(input string, maxChars int, options ...ParseOption) (string, error) {
|
||||
parsed, err := Parse(input, options...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
charsLeft := maxChars
|
||||
var result []*StyledText
|
||||
for _, element := range parsed {
|
||||
userPerceivedChars := uniseg.GraphemeClusterCount(element.Label)
|
||||
if userPerceivedChars >= charsLeft {
|
||||
var newLabel []rune
|
||||
graphemes := uniseg.NewGraphemes(element.Label)
|
||||
for graphemes.Next() {
|
||||
newLabel = append(newLabel, graphemes.Runes()...)
|
||||
charsLeft--
|
||||
if charsLeft == 0 {
|
||||
element.Label = string(newLabel)
|
||||
result = append(result, element)
|
||||
return String(result), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
result = append(result, element)
|
||||
charsLeft -= userPerceivedChars
|
||||
}
|
||||
return String(result), nil
|
||||
}
|
||||
|
||||
// Cleanse removes ANSI control symbols from the string.
|
||||
func Cleanse(input string, options ...ParseOption) (string, error) {
|
||||
if input == "" {
|
||||
return "", nil
|
||||
}
|
||||
parsed, err := Parse(input, options...)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
var result strings.Builder
|
||||
for _, element := range parsed {
|
||||
result.WriteString(element.Label)
|
||||
}
|
||||
return result.String(), nil
|
||||
}
|
||||
|
||||
// Length calculates count of user-perceived characters in ANSI string.
|
||||
func Length(input string, options ...ParseOption) (int, error) {
|
||||
if input == "" {
|
||||
return 0, nil
|
||||
}
|
||||
parsed, err := Parse(input, options...)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
var result int
|
||||
for _, element := range parsed {
|
||||
userPerceivedChars := uniseg.GraphemeClusterCount(element.Label)
|
||||
result += userPerceivedChars
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
1823
vendor/github.com/leaanthony/go-ansi-parser/cols.go
generated
vendored
Normal file
1823
vendor/github.com/leaanthony/go-ansi-parser/cols.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
vendor/github.com/leaanthony/go-ansi-parser/logo.png
generated
vendored
Normal file
BIN
vendor/github.com/leaanthony/go-ansi-parser/logo.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
25
vendor/github.com/leaanthony/go-ansi-parser/options.go
generated
vendored
Normal file
25
vendor/github.com/leaanthony/go-ansi-parser/options.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
package ansi
|
||||
|
||||
// ParseOption specifies parse option.
|
||||
type ParseOption struct {
|
||||
ignoreUnexpectedCode bool
|
||||
ansiForegroundColor string
|
||||
ansiBackgroundColor string
|
||||
}
|
||||
|
||||
// WithIgnoreInvalidCodes disables returning an error on invalid ANSI code.
|
||||
func WithIgnoreInvalidCodes() ParseOption {
|
||||
return ParseOption{ignoreUnexpectedCode: true}
|
||||
}
|
||||
|
||||
// WithDefaultForegroundColor specifies default foreground code (ANSI 39).
|
||||
// See ColourMap variable and foreground color codes 30-37.
|
||||
func WithDefaultForegroundColor(ansiColor string) ParseOption {
|
||||
return ParseOption{ansiForegroundColor: ansiColor}
|
||||
}
|
||||
|
||||
// WithDefaultBackgroundColor specifies default foreground code (ANSI 49).
|
||||
// See ColourMap variable and foreground color codes 30-37.
|
||||
func WithDefaultBackgroundColor(ansiColor string) ParseOption {
|
||||
return ParseOption{ansiBackgroundColor: ansiColor}
|
||||
}
|
||||
17
vendor/github.com/leaanthony/gosod/.gitignore
generated
vendored
Normal file
17
vendor/github.com/leaanthony/gosod/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
generated
|
||||
examples/ignore/ignore
|
||||
examples/basic/basic
|
||||
examples/filters/filters
|
||||
21
vendor/github.com/leaanthony/gosod/LICENSE
generated
vendored
Normal file
21
vendor/github.com/leaanthony/gosod/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Lea Anthony
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
105
vendor/github.com/leaanthony/gosod/README.md
generated
vendored
Normal file
105
vendor/github.com/leaanthony/gosod/README.md
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
<p align="center" style="text-align: center">
|
||||
<img src="logo.png" width="50%"><br/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Scaffolding simplified<br/><br/>
|
||||
<a href="https://github.com/leaanthony/gosod/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg"></a>
|
||||
<a href="https://goreportcard.com/report/github.com/leaanthony/gosod"><img src="https://goreportcard.com/badge/github.com/leaanthony/gosod"/></a>
|
||||
<a href="https://godoc.org/github.com/leaanthony/gosod"><img src="https://img.shields.io/badge/godoc-reference-blue.svg"/></a>
|
||||
<a href="https://github.com/leaanthony/gosod/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" /></a>
|
||||
<a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fleaanthony%2Fgosod?ref=badge_shield" alt="FOSSA Status"><img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fleaanthony%2Fgosod.svg?type=shield"/></a>
|
||||
</p>
|
||||
|
||||
|
||||
Features:
|
||||
- Scaffold out project directories from templates
|
||||
- Uses Go's native templating engine
|
||||
- Uses `fs.FS` for input, so it works well with `go:embed` and [debme](https://github.com/leaanthony/debme)
|
||||
- Go alternative to [cookiecutter](https://github.com/cookiecutter/cookiecutter)
|
||||
|
||||
## Installation
|
||||
|
||||
`go get github.com/leaanthony/gosod`
|
||||
|
||||
## Usage
|
||||
|
||||
1. Define a template directory
|
||||
2. Define some data
|
||||
3. Extract to a target directory
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/leaanthony/gosod"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
|
||||
// mytemplate/
|
||||
// ├── custom.filtername.txt
|
||||
// ├── ignored.txt
|
||||
// ├── subdir
|
||||
// │ ├── included.txt
|
||||
// │ └── sub.tmpl.go
|
||||
// └── test.tmpl.go
|
||||
//go:embed mytemplate/*
|
||||
var mytemplate embed.FS
|
||||
|
||||
func main() {
|
||||
|
||||
// Define a new Template directory
|
||||
basic, err := gosod.New(mytemplate)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Make some config data
|
||||
myConfig := &config{
|
||||
Name: "Mat",
|
||||
}
|
||||
|
||||
// Ignore files
|
||||
basic.IgnoreFile("ignored.txt")
|
||||
|
||||
// Custom template filters
|
||||
basic.SetTemplateFilters([]string{ ".filtername", ".tmpl" })
|
||||
|
||||
// Create a new directory using the template and config
|
||||
err = basic.Extract("./generated", myConfig)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Ouput FS:
|
||||
// generated/
|
||||
// ├── custom.txt
|
||||
// ├── subdir
|
||||
// │ ├── included.txt
|
||||
// │ └── sub.go
|
||||
// └── test.go
|
||||
}
|
||||
```
|
||||
|
||||
## Template Directories
|
||||
|
||||
A template directory is simply a directory structure contianing files you wish to copy. The algorithm for copying is:
|
||||
|
||||
* Categorise all files into one of: directory, standard file and template files
|
||||
* Create the directory structure
|
||||
* Copy standard files
|
||||
* Copy template files, assembled using the given data
|
||||
|
||||
Template files, by default, are any file with ".tmpl" in their filename. To change this, use `SetTemplateFilters([]string)`. This allows you to set any number of filters.
|
||||
|
||||
Files may also be ignored by using the `IgnoreFilename(string)` method.
|
||||
|
||||
## What's with the name?
|
||||
|
||||
Google is your [friend](https://translate.google.com/?sl=cy&tl=en&text=gosod&op=translate)
|
||||
11
vendor/github.com/leaanthony/gosod/gosod.go
generated
vendored
Normal file
11
vendor/github.com/leaanthony/gosod/gosod.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package gosod
|
||||
|
||||
import (
|
||||
"github.com/leaanthony/gosod/internal/templatedir"
|
||||
"io/fs"
|
||||
)
|
||||
|
||||
// New creates a new TemplateDir structure for the given filesystem
|
||||
func New(fs fs.FS) *templatedir.TemplateDir {
|
||||
return templatedir.New(fs)
|
||||
}
|
||||
287
vendor/github.com/leaanthony/gosod/internal/templatedir/templatedir.go
generated
vendored
Normal file
287
vendor/github.com/leaanthony/gosod/internal/templatedir/templatedir.go
generated
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
package templatedir
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// TemplateDir defines a directory containing directories and files, including template files
|
||||
type TemplateDir struct {
|
||||
fs fs.FS
|
||||
templateFilters []string
|
||||
dirs []string
|
||||
standardFiles []string
|
||||
templateFiles []string
|
||||
ignoredFiles map[string]struct{}
|
||||
renameFiles map[string]string
|
||||
}
|
||||
|
||||
// New attempts to create a new TemplateDir from the given FS
|
||||
func New(fs fs.FS) *TemplateDir {
|
||||
|
||||
return &TemplateDir{
|
||||
fs: fs,
|
||||
templateFilters: []string{".tmpl"},
|
||||
ignoredFiles: make(map[string]struct{}),
|
||||
renameFiles: make(map[string]string),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// IgnoreFile will add the given filename to the list of files to ignore
|
||||
// during extraction
|
||||
func (t *TemplateDir) IgnoreFile(filename string) {
|
||||
t.ignoredFiles[filename] = struct{}{}
|
||||
}
|
||||
|
||||
// SetTemplateFilters sets the template filter. Each filename is checked to see if
|
||||
// it contains this string and if so, it is deemed to be a template file
|
||||
func (t *TemplateDir) SetTemplateFilters(filters []string) {
|
||||
t.templateFilters = filters
|
||||
}
|
||||
|
||||
func (t *TemplateDir) RenameFiles(renameFiles map[string]string) {
|
||||
t.renameFiles = renameFiles
|
||||
}
|
||||
|
||||
// Extract the templates to the given directory, using data as input
|
||||
func (t *TemplateDir) Extract(targetDirectory string, data interface{}) error {
|
||||
|
||||
// Get the absolute path
|
||||
targetDirectory, err := filepath.Abs(targetDirectory)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If the targetDirectory doesn't exist, then create it
|
||||
if _, err := os.Stat(targetDirectory); os.IsNotExist(err) == true {
|
||||
// Create the targetDirectory
|
||||
err = os.MkdirAll(targetDirectory, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Process the template files
|
||||
err = t.processTemplateDirFiles(targetDirectory, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TemplateDir) processTemplateDirFiles(targetDirectory string, data interface{}) error {
|
||||
// Categorise all files
|
||||
err := t.categoriseFiles()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create all directories
|
||||
err = t.createDirectories(targetDirectory, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Process TemplateDirs
|
||||
err = t.processTemplateDirs(targetDirectory, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Copy files
|
||||
err = t.copyFiles(targetDirectory, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TemplateDir) categoriseFiles() error {
|
||||
return fs.WalkDir(t.fs, ".", t.categoriseFile)
|
||||
}
|
||||
|
||||
func (t *TemplateDir) categoriseFile(path string, info fs.DirEntry, err error) error {
|
||||
|
||||
// Process error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Is it a directory?
|
||||
if info.IsDir() {
|
||||
// Ignore base dir
|
||||
if path != "." {
|
||||
t.dirs = append(t.dirs, path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the filename
|
||||
filename := filepath.Base(path)
|
||||
|
||||
// Is it a file we are ignoring?
|
||||
_, ignored := t.ignoredFiles[filename]
|
||||
if ignored {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Is it a template?
|
||||
for _, filter := range t.templateFilters {
|
||||
if strings.Index(filename, filter) > -1 {
|
||||
t.templateFiles = append(t.templateFiles, path)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Treat as standard file
|
||||
t.standardFiles = append(t.standardFiles, path)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TemplateDir) convertPathTarget(path string, targetDirectory string, data any) string {
|
||||
|
||||
result := filepath.Join(targetDirectory, path)
|
||||
if data == nil {
|
||||
return result
|
||||
}
|
||||
|
||||
// Load the filename as a template
|
||||
tmpl, err := template.New("filename").Parse(result)
|
||||
if err != nil {
|
||||
return result
|
||||
}
|
||||
|
||||
// Execute the template
|
||||
var buf bytes.Buffer
|
||||
err = tmpl.Execute(&buf, data)
|
||||
if err != nil {
|
||||
return result
|
||||
}
|
||||
|
||||
// Return the result
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (t *TemplateDir) createDirectories(targetDirectory string, data any) error {
|
||||
|
||||
// Iterate all directories and attempt to create them
|
||||
for _, dirPath := range t.dirs {
|
||||
|
||||
targetDir := t.convertPathTarget(dirPath, targetDirectory, data)
|
||||
|
||||
// Create the directory
|
||||
err := os.MkdirAll(targetDir, 0755)
|
||||
|
||||
// Ignore directory exists errors
|
||||
if err != nil && err != syscall.EEXIST {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TemplateDir) processTemplateDirs(targetDirectory string, data interface{}) error {
|
||||
|
||||
// Iterate template files
|
||||
for _, templateFile := range t.templateFiles {
|
||||
|
||||
// Parse template
|
||||
tmpl, err := template.ParseFS(t.fs, templateFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert path to target path
|
||||
targetFile := t.convertPathTarget(templateFile, targetDirectory, data)
|
||||
|
||||
// update filename
|
||||
baseDir := filepath.Dir(targetFile)
|
||||
filename := filepath.Base(targetFile)
|
||||
for _, filter := range t.templateFilters {
|
||||
filename = strings.ReplaceAll(filename, filter, "")
|
||||
}
|
||||
renamedFile := t.renameFiles[filename]
|
||||
if renamedFile != "" {
|
||||
filename = renamedFile
|
||||
}
|
||||
targetFile = filepath.Join(baseDir, filename)
|
||||
|
||||
// Create target file
|
||||
writer, err := os.Create(targetFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = tmpl.Execute(writer, data)
|
||||
if err != nil {
|
||||
err2 := writer.Close()
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
err = writer.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TemplateDir) copyFiles(targetDirectory string, data any) error {
|
||||
|
||||
// Iterate over files
|
||||
for _, filename := range t.standardFiles {
|
||||
targetFile := filename
|
||||
renamedFile := t.renameFiles[filename]
|
||||
if renamedFile != "" {
|
||||
targetFile = renamedFile
|
||||
}
|
||||
|
||||
targetFilename := t.convertPathTarget(targetFile, targetDirectory, data)
|
||||
err := t.copyFile(filename, targetFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TemplateDir) copyFile(source, target string) error {
|
||||
s, err := t.fs.Open(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(s fs.File) {
|
||||
err := s.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}(s)
|
||||
d, err := os.Create(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(d, s); err != nil {
|
||||
err := d.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
return d.Close()
|
||||
}
|
||||
BIN
vendor/github.com/leaanthony/gosod/logo.png
generated
vendored
Normal file
BIN
vendor/github.com/leaanthony/gosod/logo.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
13
vendor/github.com/leaanthony/slicer/.gitignore
generated
vendored
Normal file
13
vendor/github.com/leaanthony/slicer/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
coverage.txt
|
||||
39
vendor/github.com/leaanthony/slicer/CHANGELOG.md
generated
vendored
Normal file
39
vendor/github.com/leaanthony/slicer/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<a name="unreleased"></a>
|
||||
## [Unreleased]
|
||||
|
||||
|
||||
<a name="v1.3.1"></a>
|
||||
## [v1.3.1] - 2019-03-03
|
||||
### Fix
|
||||
- Fix Float tests
|
||||
|
||||
|
||||
<a name="v1.3.0"></a>
|
||||
## [v1.3.0] - 2019-03-03
|
||||
### Feat
|
||||
- Add optional slice as part of construction
|
||||
|
||||
|
||||
<a name="v1.2.0"></a>
|
||||
## [v1.2.0] - 2019-02-26
|
||||
### Chore
|
||||
- add changelog
|
||||
|
||||
### Feat
|
||||
- Add Slicer.Each()
|
||||
|
||||
|
||||
<a name="v1.1.0"></a>
|
||||
## [v1.1.0] - 2019-02-26
|
||||
### Feat
|
||||
- Added Filter
|
||||
|
||||
|
||||
<a name="v1.0.0"></a>
|
||||
## v1.0.0 - 2019-01-13
|
||||
|
||||
[Unreleased]: https://github.com/leaanthony/slicer/compare/v1.3.1...HEAD
|
||||
[v1.3.1]: https://github.com/leaanthony/slicer/compare/v1.3.0...v1.3.1
|
||||
[v1.3.0]: https://github.com/leaanthony/slicer/compare/v1.2.0...v1.3.0
|
||||
[v1.2.0]: https://github.com/leaanthony/slicer/compare/v1.1.0...v1.2.0
|
||||
[v1.1.0]: https://github.com/leaanthony/slicer/compare/v1.0.0...v1.1.0
|
||||
21
vendor/github.com/leaanthony/slicer/LICENSE
generated
vendored
Normal file
21
vendor/github.com/leaanthony/slicer/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Lea Anthony
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
216
vendor/github.com/leaanthony/slicer/README.md
generated
vendored
Normal file
216
vendor/github.com/leaanthony/slicer/README.md
generated
vendored
Normal file
@@ -0,0 +1,216 @@
|
||||
|
||||
<div style="text-align:center; width:400px">
|
||||
<img src="logo.png"/>
|
||||
Utility class for handling slices.
|
||||
</div>
|
||||
|
||||
|
||||
[](https://goreportcard.com/report/github.com/leaanthony/slicer) [](http://godoc.org/github.com/leaanthony/slicer) [](https://www.codefactor.io/repository/github/leaanthony/slicer) [](https://codecov.io/gh/leaanthony/slicer) [](https://github.com/avelino/awesome-go)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Install
|
||||
|
||||
`go get -u github.com/leaanthony/slicer`
|
||||
|
||||
## Quick Start
|
||||
|
||||
```
|
||||
import "github.com/leaanthony/slicer"
|
||||
|
||||
func test() {
|
||||
s := slicer.String()
|
||||
s.Add("one")
|
||||
s.Add("two")
|
||||
s.AddSlice([]string{"three","four"})
|
||||
fmt.Printf("My slice = %+v\n", s.AsSlice())
|
||||
|
||||
t := slicer.String()
|
||||
t.Add("zero")
|
||||
t.AddSlicer(s)
|
||||
fmt.Printf("My slice = %+v\n", t.AsSlice())
|
||||
}
|
||||
```
|
||||
|
||||
## Available slicers
|
||||
|
||||
- Int
|
||||
- Int8
|
||||
- Int16
|
||||
- Int32
|
||||
- Int64
|
||||
- UInt
|
||||
- UInt8
|
||||
- UInt16
|
||||
- UInt32
|
||||
- UInt64
|
||||
- Float32
|
||||
- Float64
|
||||
- String
|
||||
- Bool
|
||||
- Interface
|
||||
|
||||
## API
|
||||
|
||||
### Construction
|
||||
|
||||
Create new Slicers by calling one of the following functions:
|
||||
- Int()
|
||||
- Int8()
|
||||
- Int16()
|
||||
- Int32()
|
||||
- Int64()
|
||||
- Float32()
|
||||
- Float64()
|
||||
- String()
|
||||
- Bool()
|
||||
- Interface()
|
||||
|
||||
```
|
||||
s := slicer.String()
|
||||
```
|
||||
|
||||
If you wish to convert an existing slice to a Slicer, you may pass it in during creation:
|
||||
|
||||
```
|
||||
values := []string{"one", "two", "three"}
|
||||
s := slicer.String(values)
|
||||
```
|
||||
|
||||
### Add
|
||||
|
||||
Adds a value to the slice.
|
||||
|
||||
```
|
||||
values := []string{"one", "two", "three"}
|
||||
s := slicer.String(values)
|
||||
s.Add("four")
|
||||
```
|
||||
|
||||
### AddUnique
|
||||
|
||||
Adds a value to the slice if it doesn't already contain it.
|
||||
|
||||
```
|
||||
values := []string{"one", "two", "three", "one", "two", "three"}
|
||||
s := slicer.String(values)
|
||||
result := s.Join(",")
|
||||
// result is "one,two,three"
|
||||
```
|
||||
### AddSlice
|
||||
|
||||
Adds an existing slice of values to a slicer
|
||||
|
||||
```
|
||||
s := slicer.String([]string{"one"})
|
||||
s.AddSlice([]string{"two"})
|
||||
```
|
||||
|
||||
### AsSlice
|
||||
|
||||
Returns a regular slice from the slicer.
|
||||
|
||||
```
|
||||
s := slicer.String([]string{"one"})
|
||||
for _, value := range s.AsSlice() {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### AddSlicer
|
||||
|
||||
Adds an existing slicer of values to another slicer
|
||||
|
||||
```
|
||||
a := slicer.String([]string{"one"})
|
||||
b := slicer.String([]string{"two"})
|
||||
a.AddSlicer(b)
|
||||
```
|
||||
|
||||
### Filter
|
||||
|
||||
Filter the values of a slicer based on the result of calling the given function with each value of the slice. If it returns true, the value is added to the result.
|
||||
|
||||
```
|
||||
a := slicer.Int([]int{1,5,7,9,6,3,1,9,1})
|
||||
result := a.Filter(func(v int) bool {
|
||||
return v > 5
|
||||
})
|
||||
// result is []int{7,9,9}
|
||||
|
||||
```
|
||||
|
||||
### Each
|
||||
|
||||
Each iterates over all the values of a slicer, passing them in as paramter to a function
|
||||
|
||||
```
|
||||
a := slicer.Int([]int{1,5,7,9,6,3,1,9,1})
|
||||
result := 0
|
||||
a.Each(func(v int) {
|
||||
result += v
|
||||
})
|
||||
// result is 42
|
||||
```
|
||||
|
||||
### Contains
|
||||
|
||||
Contains returns true if the slicer contains the given value
|
||||
|
||||
```
|
||||
a := slicer.Int([]int{1,5,7,9,6,3,1,9,1})
|
||||
result := a.Contains(9)
|
||||
// result is True
|
||||
```
|
||||
|
||||
### Join
|
||||
|
||||
Returns a string with the slicer elements separated by the given separator
|
||||
|
||||
```
|
||||
a := slicer.String([]string{"one", "two", "three"})
|
||||
result := a.Join(",")
|
||||
// result is "one,two,three"
|
||||
```
|
||||
### Length
|
||||
|
||||
Returns the length of the slice
|
||||
|
||||
```
|
||||
a := slicer.String([]string{"one", "two", "three"})
|
||||
result := a.Length()
|
||||
// result is 3
|
||||
```
|
||||
|
||||
### Clear
|
||||
|
||||
Clears all elements from the current slice
|
||||
|
||||
```
|
||||
a := slicer.String([]string{"one", "two", "three"})
|
||||
a.Clear()
|
||||
// a.Length() == 0
|
||||
```
|
||||
|
||||
### Sort
|
||||
|
||||
Sorts the elements of a slice
|
||||
Not supported by: InterfaceSlicer, BoolSlicer
|
||||
|
||||
```
|
||||
a := slicer.Int([]int{5,3,4,1,2})
|
||||
a.Sort()
|
||||
// a is []int{1,2,3,4,5}
|
||||
```
|
||||
|
||||
### Deduplicate
|
||||
|
||||
Deduplicate removes all duplicates within a slice.
|
||||
|
||||
```
|
||||
a := slicer.Int([]int{5,3,5,1,3})
|
||||
a.Deduplicate()
|
||||
// a is []int{5,3,1}
|
||||
```
|
||||
127
vendor/github.com/leaanthony/slicer/bool.go
generated
vendored
Normal file
127
vendor/github.com/leaanthony/slicer/bool.go
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// BoolSlicer handles slices of bool
|
||||
type BoolSlicer struct {
|
||||
slice []bool
|
||||
}
|
||||
|
||||
// Bool creates a new BoolSlicer
|
||||
func Bool(slice ...[]bool) *BoolSlicer {
|
||||
if len(slice) > 0 {
|
||||
return &BoolSlicer{slice: slice[0]}
|
||||
}
|
||||
return &BoolSlicer{}
|
||||
}
|
||||
|
||||
// Add a bool value to the slicer
|
||||
func (s *BoolSlicer) Add(value bool, additional ...bool) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a bool value to the slicer if it does not already exist
|
||||
func (s *BoolSlicer) AddUnique(value bool, additional ...bool) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a bool slice to the slicer
|
||||
func (s *BoolSlicer) AddSlice(value []bool) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *BoolSlicer) AsSlice() []bool {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a BoolSlicer to the slicer
|
||||
func (s *BoolSlicer) AddSlicer(value *BoolSlicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *BoolSlicer) Filter(fn func(bool) bool) *BoolSlicer {
|
||||
result := &BoolSlicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *BoolSlicer) Each(fn func(bool)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *BoolSlicer) Contains(matcher bool) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *BoolSlicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *BoolSlicer) Clear() {
|
||||
s.slice = []bool{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *BoolSlicer) Deduplicate() {
|
||||
|
||||
result := &BoolSlicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *BoolSlicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
133
vendor/github.com/leaanthony/slicer/float32.go
generated
vendored
Normal file
133
vendor/github.com/leaanthony/slicer/float32.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// Float32Slicer handles slices of float32
|
||||
type Float32Slicer struct {
|
||||
slice []float32
|
||||
}
|
||||
|
||||
// Float32 creates a new Float32Slicer
|
||||
func Float32(slice ...[]float32) *Float32Slicer {
|
||||
if len(slice) > 0 {
|
||||
return &Float32Slicer{slice: slice[0]}
|
||||
}
|
||||
return &Float32Slicer{}
|
||||
}
|
||||
|
||||
// Add a float32 value to the slicer
|
||||
func (s *Float32Slicer) Add(value float32, additional ...float32) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a float32 value to the slicer if it does not already exist
|
||||
func (s *Float32Slicer) AddUnique(value float32, additional ...float32) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a float32 slice to the slicer
|
||||
func (s *Float32Slicer) AddSlice(value []float32) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *Float32Slicer) AsSlice() []float32 {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a Float32Slicer to the slicer
|
||||
func (s *Float32Slicer) AddSlicer(value *Float32Slicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *Float32Slicer) Filter(fn func(float32) bool) *Float32Slicer {
|
||||
result := &Float32Slicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *Float32Slicer) Each(fn func(float32)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *Float32Slicer) Contains(matcher float32) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *Float32Slicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *Float32Slicer) Clear() {
|
||||
s.slice = []float32{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *Float32Slicer) Deduplicate() {
|
||||
|
||||
result := &Float32Slicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *Float32Slicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *Float32Slicer) Sort() {
|
||||
sort.Slice(s.slice, func(i, j int) bool { return s.slice[i] < s.slice[j] })
|
||||
}
|
||||
133
vendor/github.com/leaanthony/slicer/float64.go
generated
vendored
Normal file
133
vendor/github.com/leaanthony/slicer/float64.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// Float64Slicer handles slices of float64
|
||||
type Float64Slicer struct {
|
||||
slice []float64
|
||||
}
|
||||
|
||||
// Float64 creates a new Float64Slicer
|
||||
func Float64(slice ...[]float64) *Float64Slicer {
|
||||
if len(slice) > 0 {
|
||||
return &Float64Slicer{slice: slice[0]}
|
||||
}
|
||||
return &Float64Slicer{}
|
||||
}
|
||||
|
||||
// Add a float64 value to the slicer
|
||||
func (s *Float64Slicer) Add(value float64, additional ...float64) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a float64 value to the slicer if it does not already exist
|
||||
func (s *Float64Slicer) AddUnique(value float64, additional ...float64) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a float64 slice to the slicer
|
||||
func (s *Float64Slicer) AddSlice(value []float64) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *Float64Slicer) AsSlice() []float64 {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a Float64Slicer to the slicer
|
||||
func (s *Float64Slicer) AddSlicer(value *Float64Slicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *Float64Slicer) Filter(fn func(float64) bool) *Float64Slicer {
|
||||
result := &Float64Slicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *Float64Slicer) Each(fn func(float64)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *Float64Slicer) Contains(matcher float64) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *Float64Slicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *Float64Slicer) Clear() {
|
||||
s.slice = []float64{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *Float64Slicer) Deduplicate() {
|
||||
|
||||
result := &Float64Slicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *Float64Slicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *Float64Slicer) Sort() {
|
||||
sort.Slice(s.slice, func(i, j int) bool { return s.slice[i] < s.slice[j] })
|
||||
}
|
||||
133
vendor/github.com/leaanthony/slicer/int.go
generated
vendored
Normal file
133
vendor/github.com/leaanthony/slicer/int.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// IntSlicer handles slices of int
|
||||
type IntSlicer struct {
|
||||
slice []int
|
||||
}
|
||||
|
||||
// Int creates a new IntSlicer
|
||||
func Int(slice ...[]int) *IntSlicer {
|
||||
if len(slice) > 0 {
|
||||
return &IntSlicer{slice: slice[0]}
|
||||
}
|
||||
return &IntSlicer{}
|
||||
}
|
||||
|
||||
// Add a int value to the slicer
|
||||
func (s *IntSlicer) Add(value int, additional ...int) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a int value to the slicer if it does not already exist
|
||||
func (s *IntSlicer) AddUnique(value int, additional ...int) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a int slice to the slicer
|
||||
func (s *IntSlicer) AddSlice(value []int) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *IntSlicer) AsSlice() []int {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a IntSlicer to the slicer
|
||||
func (s *IntSlicer) AddSlicer(value *IntSlicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *IntSlicer) Filter(fn func(int) bool) *IntSlicer {
|
||||
result := &IntSlicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *IntSlicer) Each(fn func(int)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *IntSlicer) Contains(matcher int) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *IntSlicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *IntSlicer) Clear() {
|
||||
s.slice = []int{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *IntSlicer) Deduplicate() {
|
||||
|
||||
result := &IntSlicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *IntSlicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *IntSlicer) Sort() {
|
||||
sort.Slice(s.slice, func(i, j int) bool { return s.slice[i] < s.slice[j] })
|
||||
}
|
||||
133
vendor/github.com/leaanthony/slicer/int16.go
generated
vendored
Normal file
133
vendor/github.com/leaanthony/slicer/int16.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// Int16Slicer handles slices of int16
|
||||
type Int16Slicer struct {
|
||||
slice []int16
|
||||
}
|
||||
|
||||
// Int16 creates a new Int16Slicer
|
||||
func Int16(slice ...[]int16) *Int16Slicer {
|
||||
if len(slice) > 0 {
|
||||
return &Int16Slicer{slice: slice[0]}
|
||||
}
|
||||
return &Int16Slicer{}
|
||||
}
|
||||
|
||||
// Add a int16 value to the slicer
|
||||
func (s *Int16Slicer) Add(value int16, additional ...int16) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a int16 value to the slicer if it does not already exist
|
||||
func (s *Int16Slicer) AddUnique(value int16, additional ...int16) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a int16 slice to the slicer
|
||||
func (s *Int16Slicer) AddSlice(value []int16) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *Int16Slicer) AsSlice() []int16 {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a Int16Slicer to the slicer
|
||||
func (s *Int16Slicer) AddSlicer(value *Int16Slicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *Int16Slicer) Filter(fn func(int16) bool) *Int16Slicer {
|
||||
result := &Int16Slicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *Int16Slicer) Each(fn func(int16)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *Int16Slicer) Contains(matcher int16) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *Int16Slicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *Int16Slicer) Clear() {
|
||||
s.slice = []int16{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *Int16Slicer) Deduplicate() {
|
||||
|
||||
result := &Int16Slicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *Int16Slicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *Int16Slicer) Sort() {
|
||||
sort.Slice(s.slice, func(i, j int) bool { return s.slice[i] < s.slice[j] })
|
||||
}
|
||||
133
vendor/github.com/leaanthony/slicer/int32.go
generated
vendored
Normal file
133
vendor/github.com/leaanthony/slicer/int32.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// Int32Slicer handles slices of int32
|
||||
type Int32Slicer struct {
|
||||
slice []int32
|
||||
}
|
||||
|
||||
// Int32 creates a new Int32Slicer
|
||||
func Int32(slice ...[]int32) *Int32Slicer {
|
||||
if len(slice) > 0 {
|
||||
return &Int32Slicer{slice: slice[0]}
|
||||
}
|
||||
return &Int32Slicer{}
|
||||
}
|
||||
|
||||
// Add a int32 value to the slicer
|
||||
func (s *Int32Slicer) Add(value int32, additional ...int32) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a int32 value to the slicer if it does not already exist
|
||||
func (s *Int32Slicer) AddUnique(value int32, additional ...int32) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a int32 slice to the slicer
|
||||
func (s *Int32Slicer) AddSlice(value []int32) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *Int32Slicer) AsSlice() []int32 {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a Int32Slicer to the slicer
|
||||
func (s *Int32Slicer) AddSlicer(value *Int32Slicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *Int32Slicer) Filter(fn func(int32) bool) *Int32Slicer {
|
||||
result := &Int32Slicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *Int32Slicer) Each(fn func(int32)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *Int32Slicer) Contains(matcher int32) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *Int32Slicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *Int32Slicer) Clear() {
|
||||
s.slice = []int32{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *Int32Slicer) Deduplicate() {
|
||||
|
||||
result := &Int32Slicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *Int32Slicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *Int32Slicer) Sort() {
|
||||
sort.Slice(s.slice, func(i, j int) bool { return s.slice[i] < s.slice[j] })
|
||||
}
|
||||
133
vendor/github.com/leaanthony/slicer/int64.go
generated
vendored
Normal file
133
vendor/github.com/leaanthony/slicer/int64.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// Int64Slicer handles slices of int64
|
||||
type Int64Slicer struct {
|
||||
slice []int64
|
||||
}
|
||||
|
||||
// Int64 creates a new Int64Slicer
|
||||
func Int64(slice ...[]int64) *Int64Slicer {
|
||||
if len(slice) > 0 {
|
||||
return &Int64Slicer{slice: slice[0]}
|
||||
}
|
||||
return &Int64Slicer{}
|
||||
}
|
||||
|
||||
// Add a int64 value to the slicer
|
||||
func (s *Int64Slicer) Add(value int64, additional ...int64) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a int64 value to the slicer if it does not already exist
|
||||
func (s *Int64Slicer) AddUnique(value int64, additional ...int64) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a int64 slice to the slicer
|
||||
func (s *Int64Slicer) AddSlice(value []int64) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *Int64Slicer) AsSlice() []int64 {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a Int64Slicer to the slicer
|
||||
func (s *Int64Slicer) AddSlicer(value *Int64Slicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *Int64Slicer) Filter(fn func(int64) bool) *Int64Slicer {
|
||||
result := &Int64Slicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *Int64Slicer) Each(fn func(int64)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *Int64Slicer) Contains(matcher int64) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *Int64Slicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *Int64Slicer) Clear() {
|
||||
s.slice = []int64{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *Int64Slicer) Deduplicate() {
|
||||
|
||||
result := &Int64Slicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *Int64Slicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *Int64Slicer) Sort() {
|
||||
sort.Slice(s.slice, func(i, j int) bool { return s.slice[i] < s.slice[j] })
|
||||
}
|
||||
133
vendor/github.com/leaanthony/slicer/int8.go
generated
vendored
Normal file
133
vendor/github.com/leaanthony/slicer/int8.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// Int8Slicer handles slices of int8
|
||||
type Int8Slicer struct {
|
||||
slice []int8
|
||||
}
|
||||
|
||||
// Int8 creates a new Int8Slicer
|
||||
func Int8(slice ...[]int8) *Int8Slicer {
|
||||
if len(slice) > 0 {
|
||||
return &Int8Slicer{slice: slice[0]}
|
||||
}
|
||||
return &Int8Slicer{}
|
||||
}
|
||||
|
||||
// Add a int8 value to the slicer
|
||||
func (s *Int8Slicer) Add(value int8, additional ...int8) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a int8 value to the slicer if it does not already exist
|
||||
func (s *Int8Slicer) AddUnique(value int8, additional ...int8) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a int8 slice to the slicer
|
||||
func (s *Int8Slicer) AddSlice(value []int8) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *Int8Slicer) AsSlice() []int8 {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a Int8Slicer to the slicer
|
||||
func (s *Int8Slicer) AddSlicer(value *Int8Slicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *Int8Slicer) Filter(fn func(int8) bool) *Int8Slicer {
|
||||
result := &Int8Slicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *Int8Slicer) Each(fn func(int8)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *Int8Slicer) Contains(matcher int8) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *Int8Slicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *Int8Slicer) Clear() {
|
||||
s.slice = []int8{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *Int8Slicer) Deduplicate() {
|
||||
|
||||
result := &Int8Slicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *Int8Slicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *Int8Slicer) Sort() {
|
||||
sort.Slice(s.slice, func(i, j int) bool { return s.slice[i] < s.slice[j] })
|
||||
}
|
||||
127
vendor/github.com/leaanthony/slicer/interface.go
generated
vendored
Normal file
127
vendor/github.com/leaanthony/slicer/interface.go
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// InterfaceSlicer handles slices of interface{}
|
||||
type InterfaceSlicer struct {
|
||||
slice []interface{}
|
||||
}
|
||||
|
||||
// Interface creates a new InterfaceSlicer
|
||||
func Interface(slice ...[]interface{}) *InterfaceSlicer {
|
||||
if len(slice) > 0 {
|
||||
return &InterfaceSlicer{slice: slice[0]}
|
||||
}
|
||||
return &InterfaceSlicer{}
|
||||
}
|
||||
|
||||
// Add a interface{} value to the slicer
|
||||
func (s *InterfaceSlicer) Add(value interface{}, additional ...interface{}) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a interface{} value to the slicer if it does not already exist
|
||||
func (s *InterfaceSlicer) AddUnique(value interface{}, additional ...interface{}) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a interface{} slice to the slicer
|
||||
func (s *InterfaceSlicer) AddSlice(value []interface{}) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *InterfaceSlicer) AsSlice() []interface{} {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a InterfaceSlicer to the slicer
|
||||
func (s *InterfaceSlicer) AddSlicer(value *InterfaceSlicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *InterfaceSlicer) Filter(fn func(interface{}) bool) *InterfaceSlicer {
|
||||
result := &InterfaceSlicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *InterfaceSlicer) Each(fn func(interface{})) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *InterfaceSlicer) Contains(matcher interface{}) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *InterfaceSlicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *InterfaceSlicer) Clear() {
|
||||
s.slice = []interface{}{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *InterfaceSlicer) Deduplicate() {
|
||||
|
||||
result := &InterfaceSlicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *InterfaceSlicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
BIN
vendor/github.com/leaanthony/slicer/logo.png
generated
vendored
Normal file
BIN
vendor/github.com/leaanthony/slicer/logo.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
118
vendor/github.com/leaanthony/slicer/string.go
generated
vendored
Normal file
118
vendor/github.com/leaanthony/slicer/string.go
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "strings"
|
||||
|
||||
// StringSlicer handles slices of string
|
||||
type StringSlicer struct {
|
||||
slice []string
|
||||
}
|
||||
|
||||
// String creates a new StringSlicer
|
||||
func String(slice ...[]string) *StringSlicer {
|
||||
if len(slice) > 0 {
|
||||
return &StringSlicer{slice: slice[0]}
|
||||
}
|
||||
return &StringSlicer{}
|
||||
}
|
||||
|
||||
// Add a string value to the slicer
|
||||
func (s *StringSlicer) Add(value string, additional ...string) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a string value to the slicer if it does not already exist
|
||||
func (s *StringSlicer) AddUnique(value string, additional ...string) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a string slice to the slicer
|
||||
func (s *StringSlicer) AddSlice(value []string) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *StringSlicer) AsSlice() []string {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a StringSlicer to the slicer
|
||||
func (s *StringSlicer) AddSlicer(value *StringSlicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *StringSlicer) Filter(fn func(string) bool) *StringSlicer {
|
||||
result := &StringSlicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *StringSlicer) Each(fn func(string)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *StringSlicer) Contains(matcher string) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *StringSlicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *StringSlicer) Clear() {
|
||||
s.slice = []string{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *StringSlicer) Deduplicate() {
|
||||
|
||||
result := &StringSlicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *StringSlicer) Join(separator string) string {
|
||||
return strings.Join(s.slice, separator)
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *StringSlicer) Sort() {
|
||||
sort.Strings(s.slice)
|
||||
}
|
||||
133
vendor/github.com/leaanthony/slicer/uint.go
generated
vendored
Normal file
133
vendor/github.com/leaanthony/slicer/uint.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// UintSlicer handles slices of uint
|
||||
type UintSlicer struct {
|
||||
slice []uint
|
||||
}
|
||||
|
||||
// Uint creates a new UintSlicer
|
||||
func Uint(slice ...[]uint) *UintSlicer {
|
||||
if len(slice) > 0 {
|
||||
return &UintSlicer{slice: slice[0]}
|
||||
}
|
||||
return &UintSlicer{}
|
||||
}
|
||||
|
||||
// Add a uint value to the slicer
|
||||
func (s *UintSlicer) Add(value uint, additional ...uint) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a uint value to the slicer if it does not already exist
|
||||
func (s *UintSlicer) AddUnique(value uint, additional ...uint) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a uint slice to the slicer
|
||||
func (s *UintSlicer) AddSlice(value []uint) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *UintSlicer) AsSlice() []uint {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a UintSlicer to the slicer
|
||||
func (s *UintSlicer) AddSlicer(value *UintSlicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *UintSlicer) Filter(fn func(uint) bool) *UintSlicer {
|
||||
result := &UintSlicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *UintSlicer) Each(fn func(uint)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *UintSlicer) Contains(matcher uint) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *UintSlicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *UintSlicer) Clear() {
|
||||
s.slice = []uint{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *UintSlicer) Deduplicate() {
|
||||
|
||||
result := &UintSlicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *UintSlicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *UintSlicer) Sort() {
|
||||
sort.Slice(s.slice, func(i, j int) bool { return s.slice[i] < s.slice[j] })
|
||||
}
|
||||
133
vendor/github.com/leaanthony/slicer/uint16.go
generated
vendored
Normal file
133
vendor/github.com/leaanthony/slicer/uint16.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// Uint16Slicer handles slices of uint16
|
||||
type Uint16Slicer struct {
|
||||
slice []uint16
|
||||
}
|
||||
|
||||
// Uint16 creates a new Uint16Slicer
|
||||
func Uint16(slice ...[]uint16) *Uint16Slicer {
|
||||
if len(slice) > 0 {
|
||||
return &Uint16Slicer{slice: slice[0]}
|
||||
}
|
||||
return &Uint16Slicer{}
|
||||
}
|
||||
|
||||
// Add a uint16 value to the slicer
|
||||
func (s *Uint16Slicer) Add(value uint16, additional ...uint16) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a uint16 value to the slicer if it does not already exist
|
||||
func (s *Uint16Slicer) AddUnique(value uint16, additional ...uint16) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a uint16 slice to the slicer
|
||||
func (s *Uint16Slicer) AddSlice(value []uint16) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *Uint16Slicer) AsSlice() []uint16 {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a Uint16Slicer to the slicer
|
||||
func (s *Uint16Slicer) AddSlicer(value *Uint16Slicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *Uint16Slicer) Filter(fn func(uint16) bool) *Uint16Slicer {
|
||||
result := &Uint16Slicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *Uint16Slicer) Each(fn func(uint16)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *Uint16Slicer) Contains(matcher uint16) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *Uint16Slicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *Uint16Slicer) Clear() {
|
||||
s.slice = []uint16{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *Uint16Slicer) Deduplicate() {
|
||||
|
||||
result := &Uint16Slicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *Uint16Slicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *Uint16Slicer) Sort() {
|
||||
sort.Slice(s.slice, func(i, j int) bool { return s.slice[i] < s.slice[j] })
|
||||
}
|
||||
133
vendor/github.com/leaanthony/slicer/uint32.go
generated
vendored
Normal file
133
vendor/github.com/leaanthony/slicer/uint32.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// Uint32Slicer handles slices of uint32
|
||||
type Uint32Slicer struct {
|
||||
slice []uint32
|
||||
}
|
||||
|
||||
// Uint32 creates a new Uint32Slicer
|
||||
func Uint32(slice ...[]uint32) *Uint32Slicer {
|
||||
if len(slice) > 0 {
|
||||
return &Uint32Slicer{slice: slice[0]}
|
||||
}
|
||||
return &Uint32Slicer{}
|
||||
}
|
||||
|
||||
// Add a uint32 value to the slicer
|
||||
func (s *Uint32Slicer) Add(value uint32, additional ...uint32) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a uint32 value to the slicer if it does not already exist
|
||||
func (s *Uint32Slicer) AddUnique(value uint32, additional ...uint32) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a uint32 slice to the slicer
|
||||
func (s *Uint32Slicer) AddSlice(value []uint32) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *Uint32Slicer) AsSlice() []uint32 {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a Uint32Slicer to the slicer
|
||||
func (s *Uint32Slicer) AddSlicer(value *Uint32Slicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *Uint32Slicer) Filter(fn func(uint32) bool) *Uint32Slicer {
|
||||
result := &Uint32Slicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *Uint32Slicer) Each(fn func(uint32)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *Uint32Slicer) Contains(matcher uint32) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *Uint32Slicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *Uint32Slicer) Clear() {
|
||||
s.slice = []uint32{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *Uint32Slicer) Deduplicate() {
|
||||
|
||||
result := &Uint32Slicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *Uint32Slicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *Uint32Slicer) Sort() {
|
||||
sort.Slice(s.slice, func(i, j int) bool { return s.slice[i] < s.slice[j] })
|
||||
}
|
||||
133
vendor/github.com/leaanthony/slicer/uint64.go
generated
vendored
Normal file
133
vendor/github.com/leaanthony/slicer/uint64.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// Uint64Slicer handles slices of uint64
|
||||
type Uint64Slicer struct {
|
||||
slice []uint64
|
||||
}
|
||||
|
||||
// Uint64 creates a new Uint64Slicer
|
||||
func Uint64(slice ...[]uint64) *Uint64Slicer {
|
||||
if len(slice) > 0 {
|
||||
return &Uint64Slicer{slice: slice[0]}
|
||||
}
|
||||
return &Uint64Slicer{}
|
||||
}
|
||||
|
||||
// Add a uint64 value to the slicer
|
||||
func (s *Uint64Slicer) Add(value uint64, additional ...uint64) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a uint64 value to the slicer if it does not already exist
|
||||
func (s *Uint64Slicer) AddUnique(value uint64, additional ...uint64) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a uint64 slice to the slicer
|
||||
func (s *Uint64Slicer) AddSlice(value []uint64) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *Uint64Slicer) AsSlice() []uint64 {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a Uint64Slicer to the slicer
|
||||
func (s *Uint64Slicer) AddSlicer(value *Uint64Slicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *Uint64Slicer) Filter(fn func(uint64) bool) *Uint64Slicer {
|
||||
result := &Uint64Slicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *Uint64Slicer) Each(fn func(uint64)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *Uint64Slicer) Contains(matcher uint64) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *Uint64Slicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *Uint64Slicer) Clear() {
|
||||
s.slice = []uint64{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *Uint64Slicer) Deduplicate() {
|
||||
|
||||
result := &Uint64Slicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *Uint64Slicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *Uint64Slicer) Sort() {
|
||||
sort.Slice(s.slice, func(i, j int) bool { return s.slice[i] < s.slice[j] })
|
||||
}
|
||||
133
vendor/github.com/leaanthony/slicer/uint8.go
generated
vendored
Normal file
133
vendor/github.com/leaanthony/slicer/uint8.go
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
// Package slicer contains utility classes for handling slices
|
||||
package slicer
|
||||
|
||||
// Imports
|
||||
import "sort"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
|
||||
// Uint8Slicer handles slices of uint8
|
||||
type Uint8Slicer struct {
|
||||
slice []uint8
|
||||
}
|
||||
|
||||
// Uint8 creates a new Uint8Slicer
|
||||
func Uint8(slice ...[]uint8) *Uint8Slicer {
|
||||
if len(slice) > 0 {
|
||||
return &Uint8Slicer{slice: slice[0]}
|
||||
}
|
||||
return &Uint8Slicer{}
|
||||
}
|
||||
|
||||
// Add a uint8 value to the slicer
|
||||
func (s *Uint8Slicer) Add(value uint8, additional ...uint8) {
|
||||
s.slice = append(s.slice, value)
|
||||
s.slice = append(s.slice, additional...)
|
||||
}
|
||||
|
||||
// AddUnique adds a uint8 value to the slicer if it does not already exist
|
||||
func (s *Uint8Slicer) AddUnique(value uint8, additional ...uint8) {
|
||||
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
|
||||
// Add additional values
|
||||
for _, value := range additional {
|
||||
if !s.Contains(value) {
|
||||
s.slice = append(s.slice, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AddSlice adds a uint8 slice to the slicer
|
||||
func (s *Uint8Slicer) AddSlice(value []uint8) {
|
||||
s.slice = append(s.slice, value...)
|
||||
}
|
||||
|
||||
// AsSlice returns the slice
|
||||
func (s *Uint8Slicer) AsSlice() []uint8 {
|
||||
return s.slice
|
||||
}
|
||||
|
||||
// AddSlicer appends a Uint8Slicer to the slicer
|
||||
func (s *Uint8Slicer) AddSlicer(value *Uint8Slicer) {
|
||||
s.slice = append(s.slice, value.AsSlice()...)
|
||||
}
|
||||
|
||||
// Filter the slice based on the given function
|
||||
func (s *Uint8Slicer) Filter(fn func(uint8) bool) *Uint8Slicer {
|
||||
result := &Uint8Slicer{}
|
||||
for _, elem := range s.slice {
|
||||
if fn(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Each runs a function on every element of the slice
|
||||
func (s *Uint8Slicer) Each(fn func(uint8)) {
|
||||
for _, elem := range s.slice {
|
||||
fn(elem)
|
||||
}
|
||||
}
|
||||
|
||||
// Contains indicates if the given value is in the slice
|
||||
func (s *Uint8Slicer) Contains(matcher uint8) bool {
|
||||
result := false
|
||||
for _, elem := range s.slice {
|
||||
if elem == matcher {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// Length returns the number of elements in the slice
|
||||
func (s *Uint8Slicer) Length() int {
|
||||
return len(s.slice)
|
||||
}
|
||||
|
||||
// Clear all elements in the slice
|
||||
func (s *Uint8Slicer) Clear() {
|
||||
s.slice = []uint8{}
|
||||
}
|
||||
|
||||
// Deduplicate removes duplicate values from the slice
|
||||
func (s *Uint8Slicer) Deduplicate() {
|
||||
|
||||
result := &Uint8Slicer{}
|
||||
|
||||
for _, elem := range s.slice {
|
||||
if !result.Contains(elem) {
|
||||
result.Add(elem)
|
||||
}
|
||||
}
|
||||
|
||||
s.slice = result.AsSlice()
|
||||
}
|
||||
|
||||
// Join returns a string with the slicer elements separated by the given separator
|
||||
func (s *Uint8Slicer) Join(separator string) string {
|
||||
var builder strings.Builder
|
||||
|
||||
// Shortcut no elements
|
||||
if len(s.slice) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Iterate over length - 1
|
||||
index := 0
|
||||
for index = 0; index < len(s.slice)-1; index++ {
|
||||
builder.WriteString(fmt.Sprintf("%v%s", s.slice[index], separator))
|
||||
}
|
||||
builder.WriteString(fmt.Sprintf("%v", s.slice[index]))
|
||||
result := builder.String()
|
||||
return result
|
||||
}
|
||||
|
||||
// Sort the slice values
|
||||
func (s *Uint8Slicer) Sort() {
|
||||
sort.Slice(s.slice, func(i, j int) bool { return s.slice[i] < s.slice[j] })
|
||||
}
|
||||
1
vendor/github.com/leaanthony/u/.gitignore
generated
vendored
Normal file
1
vendor/github.com/leaanthony/u/.gitignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.idea/
|
||||
21
vendor/github.com/leaanthony/u/LICENSE
generated
vendored
Normal file
21
vendor/github.com/leaanthony/u/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023-Present Lea Anthony
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
150
vendor/github.com/leaanthony/u/README.md
generated
vendored
Normal file
150
vendor/github.com/leaanthony/u/README.md
generated
vendored
Normal file
@@ -0,0 +1,150 @@
|
||||
# u
|
||||
|
||||
u provides a simple way to create variables that are "unset" by default.
|
||||
|
||||
u is dependency free and has 100% test coverage.
|
||||
|
||||
## Why?
|
||||
|
||||
Go's default values are great most of the time, but sometimes you want to know if a value has been set or not. This is especially true when you want to know if a value has been set to its zero value or not.
|
||||
|
||||
For example, let's say you had a preferences struct like this:
|
||||
|
||||
```go
|
||||
type Preferences struct {
|
||||
UseFeatureX bool
|
||||
Threshold int
|
||||
}
|
||||
|
||||
func processPreferences(prefs Preferences) {
|
||||
// Uh oh...we're in a heap of trouble here...
|
||||
thirdPartyLibrary.EnableFeatureX(prefs.UseFeatureX)
|
||||
thirdPartyLibrary.SetThreshold(prefs.Threshold)
|
||||
}
|
||||
|
||||
func main() {
|
||||
var prefs Preferences
|
||||
processPreferences(prefs)
|
||||
}
|
||||
```
|
||||
|
||||
There is no real way to know if `UseFeatureX` or `Threshold` have been set or not.
|
||||
|
||||
Using this library we can *eliminate* this problem:
|
||||
|
||||
```go
|
||||
type Preferences struct {
|
||||
UseFeatureX u.Bool
|
||||
Threshold u.Int
|
||||
}
|
||||
|
||||
func processPreferences(prefs Preferences) {
|
||||
// #winning
|
||||
if prefs.UseFeatureX.IsSet() {
|
||||
thirdPartyLibrary.EnableFeatureX(prefs.UseFeatureX.Get())
|
||||
}
|
||||
if prefs.Threshold.IsSet() {
|
||||
thirdPartyLibrary.SetThreshold(prefs.Threshold.Get())
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
var prefs Preferences
|
||||
processPreferences(prefs)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Why should any of this matter?
|
||||
|
||||
It matters when you are working with third party libraries or frameworks that have default values that may not be the same as the Zero Go values.
|
||||
Perhaps the default value for a preference is `true` and you only want to set it if an explicit value has been specified.
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```go
|
||||
var myVar u.Int
|
||||
|
||||
// Set the value
|
||||
myVar.Set(10)
|
||||
|
||||
// Get the value
|
||||
fmt.Println(myVar.Get()) // 10
|
||||
|
||||
// Check if the value has been set
|
||||
fmt.Println(myVar.IsSet()) // true
|
||||
|
||||
// Unset the value
|
||||
myVar.Unset()
|
||||
|
||||
// Check if the value has been set
|
||||
fmt.Println(myVar.IsSet()) // false
|
||||
```
|
||||
|
||||
### Structs
|
||||
|
||||
`New` methods are provided for setting values in structs.
|
||||
|
||||
```go
|
||||
type MyStruct struct {
|
||||
MyVar u.Int
|
||||
MyOption u.Bool
|
||||
}
|
||||
|
||||
myStruct := MyStruct{
|
||||
MyVar: u.NewInt(42),
|
||||
MyOption: u.True,
|
||||
}
|
||||
```
|
||||
|
||||
## Why not use pointer values?
|
||||
|
||||
Yes, that's one way you can solve this issue. Personally, I try to avoid having pointer values as it increases the chance of dereferencing errors. It also feels like a hacky approach to the problem which is one missed test away from a runtime error.
|
||||
|
||||
## Supported types
|
||||
|
||||
- `u.Bool`
|
||||
- `u.Int`
|
||||
- `u.Int8`
|
||||
- `u.Int16`
|
||||
- `u.Int32`
|
||||
- `u.Int64`
|
||||
- `u.Uint`
|
||||
- `u.Uint8`
|
||||
- `u.Uint16`
|
||||
- `u.Uint32`
|
||||
- `u.Uint64`
|
||||
- `u.Float32`
|
||||
- `u.Float64`
|
||||
- `u.Complex64`
|
||||
- `u.Complex128`
|
||||
- `u.String`
|
||||
- `u.Byte`
|
||||
- `u.Rune`
|
||||
|
||||
## Values
|
||||
|
||||
- `u.True`
|
||||
- `u.False`
|
||||
|
||||
## Custom types
|
||||
|
||||
Any type can be used with this library by creating a `u.Var` of that type. For example:
|
||||
|
||||
```go
|
||||
|
||||
type MyCustomType struct {
|
||||
value string
|
||||
}
|
||||
|
||||
var myVar u.Var[MyCustomType]
|
||||
|
||||
// Set the value
|
||||
myVar.Set(MyCustomType{value: "hello"})
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
186
vendor/github.com/leaanthony/u/u.go
generated
vendored
Normal file
186
vendor/github.com/leaanthony/u/u.go
generated
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
package u
|
||||
|
||||
// True is a `bool` that is set to true
|
||||
var True = NewBool(true)
|
||||
|
||||
// False is a `bool` that is set to false
|
||||
var False = NewBool(false)
|
||||
|
||||
// Bool is a `bool` that can be unset
|
||||
type Bool = Var[bool]
|
||||
|
||||
// NewBool creates a new Bool with the given value
|
||||
func NewBool(val bool) Bool {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// String is a `string` that can be unset
|
||||
type String = Var[string]
|
||||
|
||||
// NewString creates a new String with the given value
|
||||
func NewString(val string) String {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Float64 is a `float64` that can be unset
|
||||
type Float64 = Var[float64]
|
||||
|
||||
// NewFloat64 creates a new Float64 with the given value
|
||||
func NewFloat64(val float64) Float64 {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Float32 is a `float32` that can be unset
|
||||
type Float32 = Var[float32]
|
||||
|
||||
// NewFloat32 creates a new Float32 with the given value
|
||||
func NewFloat32(val float32) Float32 {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Uint is a `uint` that can be unset
|
||||
type Uint = Var[uint]
|
||||
|
||||
// NewUint creates a new Uint with the given value
|
||||
func NewUint(val uint) Uint {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Uint8 is a `uint8` that can be unset
|
||||
type Uint8 = Var[uint8]
|
||||
|
||||
// NewUint8 creates a new Uint8 with the given value
|
||||
func NewUint8(val uint8) Uint8 {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Uint16 is a `uint16` that can be unset
|
||||
type Uint16 = Var[uint16]
|
||||
|
||||
// NewUint16 creates a new Uint16 with the given value
|
||||
func NewUint16(val uint16) Uint16 {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Uint32 is a `uint32` that can be unset
|
||||
type Uint32 = Var[uint32]
|
||||
|
||||
// NewUint32 creates a new Uint32 with the given value
|
||||
func NewUint32(val uint32) Uint32 {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Uint64 is a `uint64` that can be unset
|
||||
type Uint64 = Var[uint64]
|
||||
|
||||
// NewUint64 creates a new Uint64 with the given value
|
||||
func NewUint64(val uint64) Uint64 {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Byte is a `byte` that can be unset
|
||||
type Byte = Var[byte]
|
||||
|
||||
// NewByte creates a new Byte with the given value
|
||||
func NewByte(val byte) Byte {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Rune is a `rune` that can be unset
|
||||
type Rune = Var[rune]
|
||||
|
||||
// NewRune creates a new Rune with the given value
|
||||
func NewRune(val rune) Rune {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Complex64 is a `complex64` that can be unset
|
||||
type Complex64 = Var[complex64]
|
||||
|
||||
// NewComplex64 creates a new Complex64 with the given value
|
||||
func NewComplex64(val complex64) Complex64 {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Complex128 is a `complex128` that can be unset
|
||||
type Complex128 = Var[complex128]
|
||||
|
||||
// NewComplex128 creates a new Complex128 with the given value
|
||||
func NewComplex128(val complex128) Complex128 {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Int is an `int` that can be unset
|
||||
type Int = Var[int]
|
||||
|
||||
// NewInt creates a new Int with the given value
|
||||
func NewInt(val int) Int {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Int8 is an `int8` that can be unset
|
||||
type Int8 = Var[int8]
|
||||
|
||||
// NewInt8 creates a new Int8 with the given value
|
||||
func NewInt8(val int8) Int8 {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Int16 is an `int16` that can be unset
|
||||
type Int16 = Var[int16]
|
||||
|
||||
// NewInt16 creates a new Int16 with the given value
|
||||
func NewInt16(val int16) Int16 {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Int32 is an `int32` that can be unset
|
||||
type Int32 = Var[int32]
|
||||
|
||||
// NewInt32 creates a new Int32 with the given value
|
||||
func NewInt32(val int32) Int32 {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Int64 is an `int64` that can be unset
|
||||
type Int64 = Var[int64]
|
||||
|
||||
// NewInt64 creates a new Int64 with the given value
|
||||
func NewInt64(val int64) Int64 {
|
||||
return NewVar(val)
|
||||
}
|
||||
|
||||
// Var is a variable that can be set, unset and queried for its state.
|
||||
type Var[T any] struct {
|
||||
val T
|
||||
set bool
|
||||
}
|
||||
|
||||
// Get the value of the variable
|
||||
// Returns the zero value if unset
|
||||
func (v *Var[T]) Get() T {
|
||||
return v.val
|
||||
}
|
||||
|
||||
// Set the value of the variable
|
||||
func (v *Var[T]) Set(val T) {
|
||||
v.val = val
|
||||
v.set = true
|
||||
}
|
||||
|
||||
// IsSet returns true when a value has been set
|
||||
func (v *Var[T]) IsSet() bool {
|
||||
return v.set
|
||||
}
|
||||
|
||||
// Unset resets the value to the zero value and sets the variable to "unset"
|
||||
func (v *Var[T]) Unset() {
|
||||
v.set = false
|
||||
var temp T
|
||||
v.val = temp
|
||||
}
|
||||
|
||||
// NewVar creates a new Var with the given value
|
||||
func NewVar[T any](val T) Var[T] {
|
||||
return Var[T]{val: val, set: true}
|
||||
}
|
||||
Reference in New Issue
Block a user