Skip to content

Instantly share code, notes, and snippets.

@gjolund
Last active September 11, 2024 15:38
Show Gist options
  • Save gjolund/1b6a8587d79b84c7959efd12943d8161 to your computer and use it in GitHub Desktop.
Save gjolund/1b6a8587d79b84c7959efd12943d8161 to your computer and use it in GitHub Desktop.
Go Generics Test
// shell_args/main.go
package types
import (
"fmt"
"strings"
)
type ShellArgValue interface {
string | bool
}
// ShellArg represents a key-value pair.
type ShellArg[T ShellArgValue] struct {
Key string
Shorthand string
Usage string
Value T
}
// Helper function to determine if the value should be appended.
// The second parameter `appendFalse` allows appending false boolean values if set to true.
func shouldAppend[T ShellArgValue](value T, appendFalse ...bool) bool {
// By default, don't append false values.
shouldAppendFalse := false
if len(appendFalse) > 0 {
shouldAppendFalse = appendFalse[0]
}
switch v := any(value).(type) {
case string:
return v != "" // Append if the string is not empty
case bool:
// Append true or false based on the `appendFalse` flag
return v || shouldAppendFalse
default:
return false // Default to not appending for any other case
}
}
// Generic function that accepts string or bool values.
func formatArgument[T ShellArgValue](template string, key string, values ...T) string {
var formattedValues []any
formattedValues = append(formattedValues, key)
// Process the values and format them.
if len(values) > 0 {
for _, val := range values {
switch v := any(val).(type) {
case string:
formattedValues = append(formattedValues, v)
case bool:
formattedValues = append(formattedValues, fmt.Sprintf("%t", v))
}
}
}
// Use variadic arguments in Sprintf.
return fmt.Sprintf(template, formattedValues...)
}
// FormatNamedArgument formats the ShellArg as a named argument
// example: --key=value
func (arg *ShellArg[T]) FormatNamedArgument() string {
return formatArgument("--%s=%s", arg.Key, arg.Value)
}
// AppendNamedArgument will append a named argument to an arg array
// example: [email protected] or --enabled=false
func (arg *ShellArg[T]) AppendNamedArgument(args *[]string) {
if shouldAppend(arg.Value, true) {
*args = append(*args, arg.FormatNamedArgument())
}
}
// FormatOptionArgument formats the ShellArgString as an option argument (e.g., key=value).
func (arg *ShellArg[T]) FormatOptionArgument() string {
return formatArgument("%s=%s", arg.Key, arg.Value)
}
// AppendOptionArgument will append an option argument to an arg array with a given flag if defined
// example -e [email protected] -e enabled=false
func (arg *ShellArg[T]) AppendOptionArgument(args *[]string, flag string) {
if shouldAppend(arg.Value, true) {
*args = append(*args, flag)
*args = append(*args, arg.FormatOptionArgument())
}
}
// FormatBooleanArgument formats the ShellArg as a boolean argument
// example: --key
func (arg *ShellArg[T]) FormatBooleanArgument() string {
return formatArgument[bool]("--%s", arg.Key)
}
// AppendBooleanArgument will append a boolean argument to an arg array
// example: --email --enabled
func (arg *ShellArg[T]) AppendBooleanArgument(args *[]string) {
if shouldAppend(arg.Value) {
*args = append(*args, arg.FormatBooleanArgument())
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment