save the edited JSON

develop
skanehira 5 years ago
parent baa39d60f5
commit 483c604c64

@ -7,6 +7,7 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
"strconv"
"strings" "strings"
"github.com/gdamore/tcell" "github.com/gdamore/tcell"
@ -165,18 +166,18 @@ func (g *Gui) SaveJSON() {
fileName := form.GetFormItem(0).(*tview.InputField).GetText() fileName := form.GetFormItem(0).(*tview.InputField).GetText()
fileName = os.ExpandEnv(fileName) fileName = os.ExpandEnv(fileName)
var b bytes.Buffer var buf bytes.Buffer
enc := json.NewEncoder(&b) enc := json.NewEncoder(&buf)
enc.SetIndent("", " ") enc.SetIndent("", " ")
if err := enc.Encode(g.Tree.OriginJSON); err != nil { if err := enc.Encode(g.makeJSON(g.Tree.GetRoot())); err != nil {
msg := fmt.Sprintf("can't make json: %s", err) msg := fmt.Sprintf("can't marshal json: %s", err)
log.Println(msg) log.Println(msg)
g.Message(msg, "main", func() {}) g.Message(msg, "main", func() {})
return return
} }
if err := ioutil.WriteFile(fileName, b.Bytes(), 0666); err != nil { if err := ioutil.WriteFile(fileName, buf.Bytes(), 0666); err != nil {
msg := fmt.Sprintf("can't create file: %s", err) msg := fmt.Sprintf("can't create file: %s", err)
log.Println(msg) log.Println(msg)
g.Message(msg, "main", func() {}) g.Message(msg, "main", func() {})
@ -193,3 +194,53 @@ func (g *Gui) SaveJSON() {
g.Pages.AddAndSwitchToPage(pageName, g.Modal(form, 0, 8), true).ShowPage("main") g.Pages.AddAndSwitchToPage(pageName, g.Modal(form, 0, 8), true).ShowPage("main")
} }
func (g *Gui) makeJSON(node *tview.TreeNode) interface{} {
nodeType := node.GetReference().(Type)
children := node.GetChildren()
switch nodeType {
case Root:
if len(children) == 1 {
return g.makeJSON(children[0])
} else {
var i []interface{}
for _, n := range children {
i = append(i, g.makeJSON(n))
}
return i
}
case Object:
i := make(map[string]interface{})
for _, n := range children {
i[n.GetText()] = g.makeJSON(n)
}
return i
case Array:
var i []interface{}
for _, n := range children {
i = append(i, g.makeJSON(n))
}
return i
case Key:
v := node.GetChildren()[0]
if v.GetReference().(Type) == Value {
return g.parseValue(v)
}
return map[string]interface{}{
node.GetText(): g.makeJSON(v),
}
}
return g.parseValue(node)
}
func (g *Gui) parseValue(node *tview.TreeNode) interface{} {
v := node.GetText()
if i, err := strconv.Atoi(v); err == nil {
return i
} else if f, err := strconv.ParseFloat(v, 64); err == nil {
return f
}
return v
}

@ -2,6 +2,7 @@ package gui
import ( import (
"fmt" "fmt"
"log"
"reflect" "reflect"
"github.com/gdamore/tcell" "github.com/gdamore/tcell"
@ -11,7 +12,6 @@ import (
type Tree struct { type Tree struct {
*tview.TreeView *tview.TreeView
OriginRoot *tview.TreeNode OriginRoot *tview.TreeNode
OriginJSON interface{}
} }
func NewTree() *Tree { func NewTree() *Tree {
@ -25,11 +25,23 @@ func NewTree() *Tree {
func (t *Tree) UpdateView(g *Gui, i interface{}) { func (t *Tree) UpdateView(g *Gui, i interface{}) {
g.App.QueueUpdateDraw(func() { g.App.QueueUpdateDraw(func() {
root := tview.NewTreeNode(".").SetChildren(t.AddNode(i)) r := reflect.ValueOf(i)
var root *tview.TreeNode
switch r.Kind() {
case reflect.Map:
root = tview.NewTreeNode("{object}").SetReference(Object)
case reflect.Slice:
root = tview.NewTreeNode("{array}").SetReference(Array)
default:
root = tview.NewTreeNode("{value}").SetReference(Key)
}
root.SetChildren(t.AddNode(i))
t.SetRoot(root).SetCurrentNode(root) t.SetRoot(root).SetCurrentNode(root)
originRoot := *root originRoot := *root
t.OriginRoot = &originRoot t.OriginRoot = &originRoot
t.OriginJSON = i
}) })
} }
@ -42,24 +54,38 @@ func (t *Tree) AddNode(node interface{}) []*tview.TreeNode {
newNode := t.NewNodeWithLiteral(k). newNode := t.NewNodeWithLiteral(k).
SetColor(tcell.ColorMediumSlateBlue). SetColor(tcell.ColorMediumSlateBlue).
SetChildren(t.AddNode(v)) SetChildren(t.AddNode(v))
r := reflect.ValueOf(v)
if r.Kind() == reflect.Slice {
newNode.SetReference(Array)
} else if r.Kind() == reflect.Map {
newNode.SetReference(Object)
} else {
newNode.SetReference(Key)
}
log.Printf("key:%v value:%v value_kind:%v", k, v, newNode.GetReference())
nodes = append(nodes, newNode) nodes = append(nodes, newNode)
} }
case []interface{}: case []interface{}:
for i, v := range node { for _, v := range node {
switch n := v.(type) { switch n := v.(type) {
case map[string]interface{}, []interface{}: case map[string]interface{}:
if reflect.ValueOf(n).Len() > 0 { r := reflect.ValueOf(n)
numberNode := tview.NewTreeNode(fmt.Sprintf("[%d]", i+1)). if r.Kind() != reflect.Slice {
SetChildren(t.AddNode(v)) objectNode := tview.NewTreeNode("{object}").
nodes = append(nodes, numberNode) SetChildren(t.AddNode(v)).SetReference(Object)
log.Printf("key:%v value:%v value_kind:%v", i, v, "object")
nodes = append(nodes, objectNode)
} }
default: default:
nodes = append(nodes, t.AddNode(v)...) nodes = append(nodes, t.AddNode(v)...)
} }
} }
default: default:
nodes = append(nodes, t.NewNodeWithLiteral(node)) log.Printf("value:%v value_kind:%v", node, "value")
nodes = append(nodes, t.NewNodeWithLiteral(node).SetReference(Value))
} }
return nodes return nodes
} }
@ -70,6 +96,10 @@ func (t *Tree) NewNodeWithLiteral(i interface{}) *tview.TreeNode {
func (t *Tree) SetKeybindings(g *Gui) { func (t *Tree) SetKeybindings(g *Gui) {
t.SetSelectedFunc(func(node *tview.TreeNode) { t.SetSelectedFunc(func(node *tview.TreeNode) {
nodeType := node.GetReference().(Type)
if nodeType == Root || nodeType == Object {
return
}
g.Input(node.GetText(), "filed", func(text string) { g.Input(node.GetText(), "filed", func(text string) {
node.SetText(text) node.SetText(text)
}) })

@ -0,0 +1,25 @@
package gui
type Type int
const (
Unknown Type = iota
Root
Object
Array
Key
Value
)
var TypeMap = map[Type]string{
Unknown: "unknown",
Root: "root",
Object: "object",
Array: "array",
Key: "key",
Value: "value",
}
func (t Type) String() string {
return TypeMap[t]
}
Loading…
Cancel
Save