63 lines
1.3 KiB
Go
63 lines
1.3 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type idRange struct {
|
|
from, to uint
|
|
}
|
|
|
|
func readRanges(r io.Reader) ([]idRange, error) {
|
|
sc := bufio.NewScanner(r)
|
|
sc.Split(scanSimpleCSV)
|
|
|
|
var ranges []idRange
|
|
for sc.Scan() {
|
|
before, after, ok := strings.Cut(sc.Text(), "-")
|
|
if !ok {
|
|
return nil, fmt.Errorf("range %q: missing dash", sc.Text())
|
|
}
|
|
from, err := strconv.ParseUint(before, 10, 0)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("range %q: %w", sc.Text(), err)
|
|
}
|
|
to, err := strconv.ParseUint(after, 10, 0)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("range %q: %w", sc.Text(), err)
|
|
}
|
|
if from > to {
|
|
return nil, fmt.Errorf("range %q: refers from higher to lower", sc.Text())
|
|
}
|
|
ranges = append(ranges, idRange{
|
|
from: uint(from),
|
|
to: uint(to),
|
|
})
|
|
}
|
|
return ranges, sc.Err()
|
|
}
|
|
|
|
func scanSimpleCSV(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
|
if atEOF && len(data) == 0 {
|
|
return 0, nil, nil
|
|
}
|
|
if i := bytes.IndexByte(data, ','); i >= 0 {
|
|
return i + 1, data[:i], nil
|
|
}
|
|
if atEOF {
|
|
if trimmed, ok := bytes.CutSuffix(data, []byte("\r\n")); ok {
|
|
return len(data), trimmed, nil
|
|
}
|
|
if trimmed, ok := bytes.CutSuffix(data, []byte{'\n'}); ok {
|
|
return len(data), trimmed, nil
|
|
}
|
|
return len(data), data, nil
|
|
}
|
|
return 0, nil, nil
|
|
}
|