util.SplitKeywords   B
last analyzed

Complexity

Conditions 7

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 14
nop 1
dl 0
loc 26
rs 8
c 0
b 0
f 0
1
package util
2
3
import (
4
	"strings"
5
	"unicode"
6
)
7
8
var (
9
	separators = &unicode.RangeTable{
10
		R16: []unicode.Range16{
11
			{0x002c, 0x002c, 1}, //comma
12
			{0x003b, 0x003b, 1}, //semicolon
13
		},
14
	}
15
	quotationMarks = &unicode.RangeTable{
16
		R16: []unicode.Range16{
17
			{0x0022, 0x0022, 1}, //quot
18
		},
19
	}
20
	trimRunes = ",; \"\t\n"
21
)
22
23
type tokenizer struct {
24
	keyword   string
25
	keywords  []string
26
	lastIndex int
27
	quotFound bool
28
}
29
30
var t tokenizer
31
32
func (t *tokenizer) addKeyword(input []rune, index int) {
33
	keyword := fetchKeyword(input, t.lastIndex, index)
34
	t.lastIndex = index
35
36
	if len(keyword) != 0 {
37
		t.append(keyword)
38
	}
39
}
40
41
func (t *tokenizer) append(keyword string) {
42
	t.keywords = append(t.keywords, keyword)
43
}
44
45
func (t *tokenizer) toggleQuot() {
46
	t.quotFound = !t.quotFound
47
}
48
49
func SplitKeywords(input string) []string {
50
	t = tokenizer{}
51
52
	runes := []rune(input)
53
	for index, r := range runes {
54
		if unicode.In(r, separators) && !t.quotFound {
55
			t.addKeyword(runes, index)
56
57
			continue
58
		}
59
60
		//end of string
61
		if index == len(runes)-1 {
62
			t.addKeyword(runes, len(runes))
63
64
			continue
65
		}
66
67
		if unicode.In(r, quotationMarks) {
68
			t.toggleQuot()
69
70
			continue
71
		}
72
	}
73
74
	return t.keywords
75
}
76
77
func fetchKeyword(runes []rune, start, end int) string {
78
	return trim(cut(runes, start, end))
79
}
80
81
func trim(s string) string {
82
	return strings.Trim(s, trimRunes)
83
}
84
85
func cut(runes []rune, start, end int) string {
86
	if end > len(runes) {
87
		end = len(runes)
88
	}
89
90
	return string(runes[start:end])
91
}
92