Skip to content

Commit

Permalink
parse: add integral-slice type parsing support
Browse files Browse the repository at this point in the history
Support functions for integral-type slice-typed flags.

Support a simple comma-separated list of integers. Let
strconv.Parse{Int,Uint} pick the base so we naturally support Go's
format for binary, hex and octal.

Use generics so we only have one implementation for each of signed and
unsigned ints.
  • Loading branch information
dfinkel committed Jan 29, 2024
1 parent d4708e8 commit ed8eb31
Show file tree
Hide file tree
Showing 2 changed files with 473 additions and 0 deletions.
46 changes: 46 additions & 0 deletions parse/integral_slice.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package parse

import (
"fmt"
"strconv"
"strings"
"unsafe"
)

// SignedIntegralSlice splits on commas and parses into a slice of integers
// Parses with strconv.ParseInt and the base set to 0 so base prefixes are available.
// Whitespace is trimmed around the integers before parsing to allow for reasonable separtion (shell word-splitting aside)
func SignedIntegralSlice[I int | int64 | int32 | int16 | int8](s string) ([]I, error) {
parts := strings.Split(s, ",")
out := make([]I, len(parts))

bitSize := int(unsafe.Sizeof(I(0)) * 8)

for i, p := range parts {
val, parseErr := strconv.ParseInt(strings.TrimSpace(p), 0, bitSize)
if parseErr != nil {
return nil, fmt.Errorf("failed to parse integer index %d: %w", i, parseErr)
}
out[i] = I(val)
}
return out, nil
}

// UnsignedIntegralSlice splits on commas and parses into a slice of integers
// Parses with strconv.ParseInt and the base set to 0 so base prefixes are available.
// Whitespace is trimmed around the integers before parsing to allow for reasonable separtion (shell word-splitting aside)
func UnsignedIntegralSlice[I uint | uint64 | uint32 | uint16 | uint8 | uintptr](s string) ([]I, error) {
parts := strings.Split(s, ",")
out := make([]I, len(parts))

bitSize := int(unsafe.Sizeof(I(0)) * 8)

for i, p := range parts {
val, parseErr := strconv.ParseUint(strings.TrimSpace(p), 0, bitSize)
if parseErr != nil {
return nil, fmt.Errorf("failed to parse integer index %d: %w", i, parseErr)
}
out[i] = I(val)
}
return out, nil
}
Loading

0 comments on commit ed8eb31

Please sign in to comment.