vise/go/router/router.go

107 lines
1.8 KiB
Go

package router
import (
"fmt"
)
type Router struct {
selectors []string
symbols map[string]string
navigable bool
}
func NewRouter() Router {
return Router{
symbols: make(map[string]string),
navigable: true,
}
}
func NewStaticRouter(symbol string) Router {
return Router{
symbols: map[string]string{"_": symbol},
navigable: false,
}
}
func(r *Router) Add(selector string, symbol string) error {
if r.symbols[selector] != "" {
return fmt.Errorf("selector %v already set to symbol %v", selector, symbol)
}
l := len(selector)
if (l > 255) {
return fmt.Errorf("selector too long (is %v, max 255)", l)
}
l = len(symbol)
if (l > 255) {
return fmt.Errorf("symbol too long (is %v, max 255)", l)
}
r.selectors = append(r.selectors, selector)
r.symbols[selector] = symbol
return nil
}
func(r *Router) Get(selector string) string {
return r.symbols[selector]
}
func(r *Router) Default() string {
return r.symbols["_"]
}
func(r *Router) Next() []byte {
if len(r.selectors) == 0 {
return []byte{}
}
k := r.selectors[0]
r.selectors = r.selectors[1:]
v := r.symbols[k]
if len(r.selectors) == 0 {
r.symbols = nil
} else {
delete(r.symbols, k)
}
lk := len(k)
lv := len(v)
b := []byte{uint8(lk)}
b = append(b, k...)
b = append(b, uint8(lv))
b = append(b, v...)
return b
}
func(r *Router) ToBytes() []byte {
b := []byte{}
for true {
v := r.Next()
if len(v) == 0 {
break
}
b = append(b, v...)
}
return b
}
func FromBytes(b []byte) Router {
rb := NewRouter()
navigable := true
for len(b) > 0 {
var k string
l := b[0]
if l == 0 {
navigable = false
} else {
k = string(b[1:1+l])
b = b[1+l:]
}
l = b[0]
v := string(b[1:1+l])
if !navigable {
return NewStaticRouter(v)
}
b = b[1+l:]
rb.Add(k, v)
}
return rb
}