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:
GitHub Actions
2026-05-08 12:19:18 +08:00
parent bb27566e38
commit c1a0fe2949
1320 changed files with 497125 additions and 11 deletions

21
vendor/github.com/leaanthony/go-ansi-parser/LICENSE generated vendored Normal file
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

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
View 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
View 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
View 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
View 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
View 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)
}

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

13
vendor/github.com/leaanthony/slicer/.gitignore generated vendored Normal file
View 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
View 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
View 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
View File

@@ -0,0 +1,216 @@
<div style="text-align:center; width:400px">
<img src="logo.png"/>
Utility class for handling slices.
</div>
[![Go Report Card](https://goreportcard.com/badge/github.com/leaanthony/slicer)](https://goreportcard.com/report/github.com/leaanthony/slicer) [![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/leaanthony/slicer) [![CodeFactor](https://www.codefactor.io/repository/github/leaanthony/slicer/badge)](https://www.codefactor.io/repository/github/leaanthony/slicer) [![codecov](https://codecov.io/gh/leaanthony/slicer/branch/master/graph/badge.svg)](https://codecov.io/gh/leaanthony/slicer) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

118
vendor/github.com/leaanthony/slicer/string.go generated vendored Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View File

@@ -0,0 +1 @@
.idea/

21
vendor/github.com/leaanthony/u/LICENSE generated vendored Normal file
View 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
View 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
View 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}
}