new subcommand: eval

master
Jordan Orelli 10 years ago
parent e3bc0f82fa
commit 9d1b2b2df5

@ -43,7 +43,9 @@ func to() {
}
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 {
bail(1, "input error: %s", err)
}
@ -56,7 +58,10 @@ func to_json(n int) {
func get() {
docpath := flag.Arg(1)
doc, err := moon.Read(input(2))
in := input(2)
defer in.Close()
doc, err := moon.Read(in)
if err != nil {
bail(1, "input error: %s", err)
}
@ -71,6 +76,21 @@ func get() {
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{}) {
var w io.Writer
if status == 0 {
@ -91,8 +111,10 @@ func main() {
to()
case "get":
get()
case "eval":
eval()
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:
bail(1, "no such action:%s", flag.Arg(0))
}

@ -1,6 +1,7 @@
package moon
import (
"bytes"
"encoding/json"
"fmt"
"reflect"
@ -16,6 +17,24 @@ func (d *Doc) MarshalJSON() ([]byte, error) {
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 {
if d.items == nil {
return fmt.Errorf("no item found at path %s (doc is empty)", path)

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