135 lines
2.2 KiB
Go
135 lines
2.2 KiB
Go
|
package irc
|
||
|
|
||
|
import (
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"sync"
|
||
|
)
|
||
|
|
||
|
type Features struct {
|
||
|
m map[string]interface{}
|
||
|
lock sync.Mutex
|
||
|
}
|
||
|
|
||
|
func NewFeatures() *Features {
|
||
|
return &Features{
|
||
|
m: map[string]interface{}{},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (f *Features) Map() map[string]interface{} {
|
||
|
m := map[string]interface{}{}
|
||
|
f.lock.Lock()
|
||
|
for k, v := range f.m {
|
||
|
m[k] = v
|
||
|
}
|
||
|
f.lock.Unlock()
|
||
|
return m
|
||
|
}
|
||
|
|
||
|
func (f *Features) Parse(params []string) {
|
||
|
f.lock.Lock()
|
||
|
for _, param := range params[1 : len(params)-1] {
|
||
|
key, val := splitParam(param)
|
||
|
if key == "" {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
if key[0] == '-' {
|
||
|
delete(f.m, key[1:])
|
||
|
} else {
|
||
|
if t, ok := featureTransforms[key]; ok {
|
||
|
f.m[key] = t(val)
|
||
|
} else {
|
||
|
f.m[key] = val
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
f.lock.Unlock()
|
||
|
}
|
||
|
|
||
|
func (f *Features) Has(key string) bool {
|
||
|
f.lock.Lock()
|
||
|
_, has := f.m[key]
|
||
|
f.lock.Unlock()
|
||
|
return has
|
||
|
}
|
||
|
|
||
|
func (f *Features) Get(key string) interface{} {
|
||
|
f.lock.Lock()
|
||
|
v := f.m[key]
|
||
|
f.lock.Unlock()
|
||
|
return v
|
||
|
}
|
||
|
|
||
|
func (f *Features) String(key string) string {
|
||
|
if v, ok := f.Get(key).(string); ok {
|
||
|
return v
|
||
|
}
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
func (f *Features) Int(key string) int {
|
||
|
if v, ok := f.Get(key).(int); ok {
|
||
|
return v
|
||
|
}
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
type featureTransform func(interface{}) interface{}
|
||
|
|
||
|
func toInt(v interface{}) interface{} {
|
||
|
s := v.(string)
|
||
|
if s == "" {
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
i, _ := strconv.Atoi(s)
|
||
|
return i
|
||
|
}
|
||
|
|
||
|
func toCharList(v interface{}) interface{} {
|
||
|
s := v.(string)
|
||
|
list := make([]string, len(s))
|
||
|
for i := range s {
|
||
|
list[i] = s[i : i+1]
|
||
|
}
|
||
|
return list
|
||
|
}
|
||
|
|
||
|
func parseChanlimit(v interface{}) interface{} {
|
||
|
limits := map[string]int{}
|
||
|
|
||
|
pairs := strings.Split(v.(string), ",")
|
||
|
for _, p := range pairs {
|
||
|
pair := strings.Split(p, ":")
|
||
|
|
||
|
if len(pair) == 2 {
|
||
|
prefixes := pair[0]
|
||
|
limit, _ := strconv.Atoi(pair[1])
|
||
|
|
||
|
for i := range prefixes {
|
||
|
limits[prefixes[i:i+1]] = limit
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return limits
|
||
|
}
|
||
|
|
||
|
var featureTransforms = map[string]featureTransform{
|
||
|
"AWAYLEN": toInt,
|
||
|
"CHANLIMIT": parseChanlimit,
|
||
|
"CHANNELLEN": toInt,
|
||
|
"CHANTYPES": toCharList,
|
||
|
"HOSTLEN": toInt,
|
||
|
"KICKLEN": toInt,
|
||
|
"MAXCHANNELS": toInt,
|
||
|
"MAXTARGETS": toInt,
|
||
|
"MODES": toInt,
|
||
|
"NICKLEN": toInt,
|
||
|
"TOPICLEN": toInt,
|
||
|
"USERLEN": toInt,
|
||
|
}
|