diff --git a/go/router/router.go b/go/router/router.go deleted file mode 100644 index 3a099b0..0000000 --- a/go/router/router.go +++ /dev/null @@ -1,135 +0,0 @@ -package router - -import ( - "fmt" -) - -// Router contains and parses the routing section of the bytecode for a node. -type Router struct { - selectors []string - symbols map[string]string -} - -// NewRouter creates a new Router object. -func NewRouter() Router { - return Router{ - symbols: make(map[string]string), - } -} - -// NewStaticRouter creates a new Router object with a single destination. -// -// Used for routes that consume input value instead of navigation choices. -func NewStaticRouter(symbol string) Router { - return Router{ - symbols: map[string]string{"_": symbol}, - } -} - -// Add associates a selector with a destination symbol. -// -// Fails if: -// - selector or symbol value is invalid -// - selector already exists -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) - } - if selector[0] == '_' { - return fmt.Errorf("Invalid selector prefix '_'") - } - 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 -} - -// Get retrieve symbol for selector. -// -// Returns an empty string if selector does not exist. -// -// Will always return an empty string if the router is static. -func(r *Router) Get(selector string) string { - return r.symbols[selector] -} - -// Get the statically defined symbol destination. -// -// Returns an empty string if not a static router. -func(r *Router) Default() string { - return r.symbols["_"] -} - -// Next removes one selector from the list of registered selectors. -// -// It returns it together with it associated value in bytecode form. -// -// Returns an empty byte array if no more selectors remain. -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 -} - -// ToBytes consume all selectors and values and returns them in sequence in bytecode form. -// -// This is identical to concatenating all returned values from non-empty Next() results. -func(r *Router) ToBytes() []byte { - b := []byte{} - for true { - v := r.Next() - if len(v) == 0 { - break - } - b = append(b, v...) - } - return b -} - -// Restore a Router from bytecode. -// -// FromBytes(ToBytes()) creates an identical object. -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 -} diff --git a/go/router/router_test.go b/go/router/router_test.go deleted file mode 100644 index 6cba085..0000000 --- a/go/router/router_test.go +++ /dev/null @@ -1,89 +0,0 @@ -package router - -import ( - "bytes" - "testing" -) - -func TestRouter(t *testing.T) { - r := NewRouter() - err := r.Add("foo", "bar") - if err != nil { - t.Error(err) - } - err = r.Add("baz", "barbarbar") - if err != nil { - t.Error(err) - } - err = r.Add("foo", "xyzzy") - if err == nil { - t.Errorf("expected error for duplicate key foo") - } -} - -func TestRouterOut(t *testing.T) { - rt := NewRouter() - err := rt.Add("foo", "inky") - if err != nil { - t.Error(err) - } - err = rt.Add("barbar", "pinky") - if err != nil { - t.Error(err) - } - err = rt.Add("bazbazbaz", "blinky") - if err != nil { - t.Error(err) - } - rb := []byte{} - r := rt.Next() - expect := append([]byte{0x3}, []byte("foo")...) - expect = append(expect, 4) - expect = append(expect, []byte("inky")...) - if !bytes.Equal(r, expect) { - t.Errorf("expected %v, got %v", expect, r) - } - rb = append(rb, r...) - - r = rt.Next() - expect = append([]byte{0x6}, []byte("barbar")...) - expect = append(expect, 5) - expect = append(expect, []byte("pinky")...) - if !bytes.Equal(r, expect) { - t.Errorf("expected %v, got %v", expect, r) - } - rb = append(rb, r...) - - r = rt.Next() - expect = append([]byte{0x9}, []byte("bazbazbaz")...) - expect = append(expect, 6) - expect = append(expect, []byte("blinky")...) - if !bytes.Equal(r, expect) { - t.Errorf("expected %v, got %v", expect, r) - } - rb = append(rb, r...) -} - -func TestSerialize(t *testing.T) { - rt := NewRouter() - err := rt.Add("foo", "inky") - if err != nil { - t.Error(err) - } - err = rt.Add("barbar", "pinky") - if err != nil { - t.Error(err) - } - err = rt.Add("bazbazbaz", "blinky") - if err != nil { - t.Error(err) - } - - // Serialize and deserialize. - ra := rt.ToBytes() - rt = FromBytes(ra) - rb := rt.ToBytes() - if !bytes.Equal(ra, rb) { - t.Errorf("expected %v, got %v", ra, rb) - } -}