/
tag.go
69 lines (64 loc) · 1.18 KB
/
tag.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
package psql
// parseTagData converts a tag into a column name (or empty if none) and parameters
//
// It can parse various syntaxes:
//
// Col string `sql:",size=foo,baz=bar"`
// Col string `sql:",type=enum,values='a,b,c'"`
func parseTagData(tag string) (string, map[string]string) {
state := 0
col := ""
attrs := make(map[string]string)
first := true
var a, b []rune
var q rune
// read rune by rune
for _, c := range tag {
switch state {
case 0: // reading key
switch c {
case '=':
state = 1
case ',':
if first {
col = string(a)
first = false
} else {
attrs[string(a)] = ""
}
a = nil
default:
a = append(a, c)
}
case 1: // reading value
switch c {
case '\'', '"':
q = c
state = 2
case ',':
attrs[string(a)] = string(b)
a, b = nil, nil
state = 0
default:
b = append(b, c)
}
case 2: // in quotes
if c == q {
// out of quote
state = 1
} else {
b = append(b, c)
}
}
}
if len(a) > 0 {
if first {
col = string(a)
} else {
// add final value
attrs[string(a)] = string(b)
}
}
//log.Printf("parsed %s into %s => %v", tag, col, attrs)
return col, attrs
}