new subcommand: eval

master
Jordan Orelli 10 years ago
parent e3bc0f82fa
commit 9d1b2b2df5

@ -43,7 +43,9 @@ func to() {
} }
func to_json(n int) { func to_json(n int) {
doc, err := moon.Read(input(n)) in := input(n)
defer in.Close()
doc, err := moon.Read(in)
if err != nil { if err != nil {
bail(1, "input error: %s", err) bail(1, "input error: %s", err)
} }
@ -56,7 +58,10 @@ func to_json(n int) {
func get() { func get() {
docpath := flag.Arg(1) docpath := flag.Arg(1)
doc, err := moon.Read(input(2)) in := input(2)
defer in.Close()
doc, err := moon.Read(in)
if err != nil { if err != nil {
bail(1, "input error: %s", err) bail(1, "input error: %s", err)
} }
@ -71,6 +76,21 @@ func get() {
os.Stdout.Write(b) os.Stdout.Write(b)
} }
func eval() {
in := input(1)
defer in.Close()
doc, err := moon.Read(in)
if err != nil {
bail(1, "input error: %s", err)
}
b, err := moon.Encode(doc)
if err != nil {
bail(1, "output error: %s", err)
}
os.Stdout.Write(b)
}
func bail(status int, t string, args ...interface{}) { func bail(status int, t string, args ...interface{}) {
var w io.Writer var w io.Writer
if status == 0 { if status == 0 {
@ -91,8 +111,10 @@ func main() {
to() to()
case "get": case "get":
get() get()
case "eval":
eval()
case "": case "":
bail(1, "must specify an action.\nvalid actions: check to get") bail(1, "must specify an action.\nvalid actions: check to get eval")
default: default:
bail(1, "no such action:%s", flag.Arg(0)) bail(1, "no such action:%s", flag.Arg(0))
} }

@ -1,6 +1,7 @@
package moon package moon
import ( import (
"bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"reflect" "reflect"
@ -16,6 +17,24 @@ func (d *Doc) MarshalJSON() ([]byte, error) {
return json.Marshal(d.items) return json.Marshal(d.items)
} }
func (d *Doc) MarshalMoon() ([]byte, error) {
var buf bytes.Buffer
for k, v := range d.items {
buf.WriteString(k)
buf.WriteByte(':')
buf.WriteByte(' ')
b, err := Encode(v)
if err != nil {
return nil, err
}
if _, err := buf.Write(b); err != nil {
return nil, err
}
buf.WriteByte('\n')
}
return buf.Bytes(), nil
}
func (d *Doc) Get(path string, dest interface{}) error { func (d *Doc) Get(path string, dest interface{}) error {
if d.items == nil { if d.items == nil {
return fmt.Errorf("no item found at path %s (doc is empty)", path) return fmt.Errorf("no item found at path %s (doc is empty)", path)

@ -9,6 +9,10 @@ import (
"strconv" "strconv"
) )
type Marshaler interface {
MarshalMoon() ([]byte, error)
}
func Encode(v interface{}) ([]byte, error) { func Encode(v interface{}) ([]byte, error) {
e := &encoder{} e := &encoder{}
if err := e.encode(v); err != nil { if err := e.encode(v); err != nil {
@ -52,7 +56,15 @@ func valueEncoder(v reflect.Value) encodeFn {
return typeEncoder(v.Type()) return typeEncoder(v.Type())
} }
var (
marshalerType = reflect.TypeOf(new(Marshaler)).Elem()
)
func typeEncoder(t reflect.Type) encodeFn { func typeEncoder(t reflect.Type) encodeFn {
if t.Implements(marshalerType) {
return marshalerEncoder
}
switch t.Kind() { switch t.Kind() {
case reflect.Bool: case reflect.Bool:
return encodeBool return encodeBool
@ -70,6 +82,8 @@ func typeEncoder(t reflect.Type) encodeFn {
return encodeSlice return encodeSlice
case reflect.Interface: case reflect.Interface:
return encodeInterface return encodeInterface
case reflect.Ptr:
return encodePointer
case reflect.Map: case reflect.Map:
return encodeMap return encodeMap
default: default:
@ -187,3 +201,24 @@ func encodeMap(e *encoder, v reflect.Value) {
} }
e.WriteByte('}') e.WriteByte('}')
} }
func encodePointer(e *encoder, v reflect.Value) {
if v.IsNil() {
e.WriteString("null")
return
}
e.encodeValue(v.Elem())
}
func marshalerEncoder(e *encoder, v reflect.Value) {
if v.Kind() == reflect.Ptr && v.IsNil() {
e.WriteString("null")
return
}
m := v.Interface().(Marshaler)
b, err := m.MarshalMoon()
if err != nil {
panic(err)
}
e.Write(b)
}

Loading…
Cancel
Save