-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathseq.go
88 lines (80 loc) · 2.21 KB
/
seq.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// Copyright (c) 2020-2022 The seq developers. All rights reserved.
// Project site: https://github.com/goinvest/seq
// Use of this source code is governed by a MIT-style license that
// can be found in the LICENSE file for the project.
package seq
import (
"encoding/json"
"fmt"
"sort"
"strconv"
"strings"
)
// Int converts JSON range strings into a slice of int.s
type Int []int
// Parse parses a string into an integer slice. If the parsing fails a nil
// slice is returned.
func Parse(s string) ([]int, error) {
return newInt(s)
}
// Parsef parses a string according to a format specifier and returns the
// resulting integer slice.
func Parsef(s string, a ...interface{}) ([]int, error) {
return newInt(fmt.Sprintf(s, a...))
}
// NewInt creates a new integer sequence from a string where inclusive ranges
// of numbers are disgnated using a hyphen, and multiple sub-sequences are
// designated using a comma.
//
// "0-3" => []int{0, 1, 2, 3}
// "1-2,5-6" => []int{1, 2, 5, 6}
func NewInt(s string) (Int, error) {
var rng Int
return rng, nil
}
func newInt(s string) ([]int, error) {
var intSeq []int
if s == "" {
return intSeq, nil
}
elements := strings.Split(s, ",")
for _, element := range elements {
nums := strings.Split(element, "-")
if len(nums) == 1 {
num, err := strconv.Atoi(nums[0])
if err != nil {
return intSeq, fmt.Errorf("error converting %s to an int", nums)
}
intSeq = append(intSeq, num)
} else if len(nums) == 2 {
num1, err := strconv.Atoi(nums[0])
if err != nil {
return intSeq, fmt.Errorf("error converting %s to an int", nums)
}
num2, err := strconv.Atoi(nums[1])
if err != nil {
return intSeq, fmt.Errorf("error converting %s to an int", nums)
}
for i := num1; i <= num2; i++ {
intSeq = append(intSeq, i)
}
} else {
return intSeq, fmt.Errorf("error decoding: %s", nums)
}
}
sort.Ints(intSeq)
return intSeq, nil
}
// UnmarshalJSON implements the Unmarshaler interface for Range.
func (in *Int) UnmarshalJSON(b []byte) error {
var tmp string
if err := json.Unmarshal(b, &tmp); err != nil {
return fmt.Errorf("range should be a string, got %s", b)
}
rng, err := newInt(tmp)
if err != nil {
return err
}
*in = rng
return nil
}