diff options
Diffstat (limited to 'pkg/server/env')
| -rw-r--r-- | pkg/server/env/env.go | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/pkg/server/env/env.go b/pkg/server/env/env.go new file mode 100644 index 0000000..ab47ae8 --- /dev/null +++ b/pkg/server/env/env.go @@ -0,0 +1,114 @@ +package env + +import ( + "errors" + "regexp" + "sync" +) + +type env struct { + m map[string]string + sync.Mutex +} + +type Env struct { + *env +} + +const namePattern = "[a-zA-Z][a-zA-Z0-9]*" +var isNamePattern = regexp.MustCompile("^" + namePattern + "$").MatchString +var namePatternRe = regexp.MustCompile("@" + namePattern) + +var errBadVariable = errors.New("bad variable name") + +func New() Env { + return Env{new(env)} +} + +func (e *env) Find(key string) (string, bool) { + e.Lock() + defer e.Unlock() + + v, ok := e.m[key] + + return v, ok +} + +func (e *env) Get(key string) string { + v, _ := e.Find(key) + return v +} + +func (e *env) Set(key string, value string) error { + if !isNamePattern(key) { + return errBadVariable + } + + e.Lock() + defer e.Unlock() + + if e.m == nil { + e.m = make(map[string]string) + } + + e.m[key] = value + + return nil +} + +func (e *env) Del(key string) bool { + e.Lock() + defer e.Unlock() + + if e.m == nil { + return false + } + + if _, ok := e.m[key]; !ok { + return false + } + + delete(e.m, key) + + return true +} + +func (e *env) Each(f func (string, string) bool) { + e.Lock() + defer e.Unlock() + + for k, v := range e.m { + if !f(k, v) { + break + } + } +} + +func (e *env) Clear() { + e.Lock() + defer e.Unlock() + + e.m = nil +} + +func (e *env) Eval(s string) string { + e.Lock() + defer e.Unlock() + + repl := func (v string) string { + if v, ok := e.m[v[1:]]; ok { + return v + } + return "" + } + + for { + if t := namePatternRe.ReplaceAllStringFunc(s, repl); t == s { + break + } else { + s = t + } + } + + return s +} |
