summaryrefslogtreecommitdiff
path: root/menu/menu.go
diff options
context:
space:
mode:
Diffstat (limited to 'menu/menu.go')
-rw-r--r--menu/menu.go92
1 files changed, 92 insertions, 0 deletions
diff --git a/menu/menu.go b/menu/menu.go
new file mode 100644
index 0000000..3916649
--- /dev/null
+++ b/menu/menu.go
@@ -0,0 +1,92 @@
+package menu
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "os"
+)
+
+type MenuItem struct {
+ Title string
+ Ident string
+ Url string
+ Children []*MenuItem
+ Parent *MenuItem
+}
+
+func (it MenuItem) IsRoot() bool {
+ return it.Parent == nil
+}
+
+type Menu struct {
+ byIdent map[string]*MenuItem
+ root *MenuItem
+}
+
+func (m Menu) Root() *MenuItem {
+ return m.root
+}
+
+func (m Menu) ByIdent(ident string) *MenuItem {
+ return m.byIdent[ident]
+}
+
+type JsonMenuItem struct {
+ Title string
+ Ident string
+ Url string
+ Children []JsonMenuItem `json:",omitempty"`
+}
+
+type JsonMenu []JsonMenuItem
+
+func (m *Menu) addJsonMenuItems(jsonItems []JsonMenuItem, parent *MenuItem) {
+ for _, jsonItem := range jsonItems {
+ item := MenuItem{
+ Title: jsonItem.Title,
+ Ident: jsonItem.Ident,
+ Url: jsonItem.Url,
+ Children: make([]*MenuItem, 0, len(jsonItem.Children)),
+ Parent: parent,
+ }
+
+ parent.Children = append(parent.Children, &item)
+ m.byIdent[jsonItem.Ident] = &item
+
+ m.addJsonMenuItems(jsonItem.Children, &item)
+ }
+}
+
+func (jm JsonMenu) toMenu() *Menu {
+ root := MenuItem{
+ Children: make([]*MenuItem, 0, len(jm)),
+ }
+
+ menu := &Menu{
+ byIdent: make(map[string]*MenuItem),
+ root: &root,
+ }
+
+ menu.addJsonMenuItems(jm, &root)
+
+ return menu
+}
+
+func Parse(r io.Reader) (*Menu, error) {
+ var jsonMenu JsonMenu
+ if err := json.NewDecoder(r).Decode(&jsonMenu); err != nil {
+ return nil, err
+ }
+ return jsonMenu.toMenu(), nil
+}
+
+func LoadFromFile(filename string) (*Menu, error) {
+ f, err := os.Open(filename)
+ if err != nil {
+ return nil, fmt.Errorf("Could not load menu from %s: %v", filename, err)
+ }
+ defer f.Close()
+
+ return Parse(f)
+}