renaming doc to object

master
Jordan Orelli 10 years ago
parent c6cbb01fa2
commit c34f8c91d9

@ -29,19 +29,19 @@ import (
"strings"
)
// Doc is a representation of a Moon document in its native form. It has no
// Object is a representation of a Moon object in its native form. It has no
// configured options and deals only with opaque types.
type Doc struct {
type Object struct {
items map[string]interface{}
}
func (d *Doc) MarshalJSON() ([]byte, error) {
return json.Marshal(d.items)
func (o *Object) MarshalJSON() ([]byte, error) {
return json.Marshal(o.items)
}
func (d *Doc) MarshalMoon() ([]byte, error) {
func (o *Object) MarshalMoon() ([]byte, error) {
var buf bytes.Buffer
for k, v := range d.items {
for k, v := range o.items {
buf.WriteString(k)
buf.WriteByte(':')
buf.WriteByte(' ')
@ -57,20 +57,23 @@ func (d *Doc) MarshalMoon() ([]byte, error) {
return buf.Bytes(), nil
}
// Get reads a value from the Moon document at a given path, assigning the
// Get reads a value from the Moon object at a given path, assigning the
// value to supplied destination pointer. The argument dest MUST be a pointer,
// otherwise Get will be unable to overwrite the value that it (should) point
// to.
//
// path may represent either a top-level key or a path to a value found within the document.
// path may represent either a top-level key or a path to a value found within the object.
//
// Let's say you have a simple document that contains just a few values:
//
// name: jordan
// city: brooklyn
//
// Calling Get("name", &name) would read the value in the document at the
// "name" key and assign it to the location pointed at by the *string name.
//
// Let's take a more complex example:
//
// @webserver: {
// host: www.example.com
// port: 80
@ -87,15 +90,15 @@ func (d *Doc) MarshalMoon() ([]byte, error) {
// retrieve the item at index 1 in that list, and then read the field named
// "host" within that item, assigning the value to the address pointed to by
// the *string named host
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)
func (o *Object) Get(path string, dest interface{}) error {
if o.items == nil {
return fmt.Errorf("no item found at path %s (object is empty)", path)
}
var v interface{}
parts := strings.Split(path, "/")
v, err := seekValue(path, parts, d.items)
v, err := seekValue(path, parts, o.items)
if err != nil {
return err
}
@ -111,11 +114,11 @@ func (d *Doc) Get(path string, dest interface{}) error {
return nil
}
// Fill takes the raw values from the Moon document and assigns them to the
// Fill takes the raw values from the Moon object and assigns them to the
// fields of the struct pointed at by dest. Dest must be a struct pointer; any
// other type for dest will result in an error. Please see the Parse
// documentation for a description of how the values will be filled.
func (d *Doc) Fill(dest interface{}) error {
func (o *Object) Fill(dest interface{}) error {
// dt = destination type
dt := reflect.TypeOf(dest)
if dt.Kind() != reflect.Ptr {
@ -132,7 +135,7 @@ func (d *Doc) Fill(dest interface{}) error {
for fname, req := range reqs {
// fv = field value
fv := dv.FieldByName(fname)
v, ok := d.items[req.name]
v, ok := o.items[req.name]
if ok {
if !fv.Type().AssignableTo(reflect.TypeOf(v)) {
return fmt.Errorf("unable to assign field %s: source type %v is not assignable to destination type %v", req.name, fv.Type(), reflect.TypeOf(v))

@ -140,3 +140,24 @@ func ExampleDoc_Get_two() {
fmt.Println(name)
// Output: sean
}
// func TestFillEmbeds(t *testing.T) {
// in := `top: {val: some_data}`
//
// var dest struct {
// Top *struct {
// Val string `name: val`
// } `name: top`
// }
//
// doc, err := ReadString(in)
// if err != nil {
// t.Error(err)
// return
// }
//
// if err := doc.Fill(&dest); err != nil {
// t.Error(err)
// return
// }
// }

@ -82,45 +82,45 @@ func bail(status int, t string, args ...interface{}) {
//
// Any value provied as a command-line argument will override the value
// supplied by the config file at "./config"
func Parse(dest interface{}) *Doc {
func Parse(dest interface{}) *Object {
cliArgs, err := parseArgs(os.Args, dest)
if err != nil {
bail(1, "unable to parse cli args: %s", err)
}
var doc *Doc
var obj *Object
if Path != "" {
f, err := os.Open(Path)
if err == nil {
defer f.Close()
d, err := Read(f)
o, err := Read(f)
if err != nil {
bail(1, "unable to parse moon config file at path %s: %s", Path, err)
}
doc = d
obj = o
}
}
if doc == nil {
doc = &Doc{items: make(map[string]interface{})}
if obj == nil {
obj = &Object{items: make(map[string]interface{})}
}
for k, v := range cliArgs {
doc.items[k] = v
obj.items[k] = v
}
if err := doc.Fill(dest); err != nil {
if err := obj.Fill(dest); err != nil {
bail(1, "unable to fill moon config values: %s", err)
}
return doc
return obj
}
// Reads a moon document from a given io.Reader. The io.Reader is advanced to
// Reads a moon object from a given io.Reader. The io.Reader is advanced to
// EOF. The reader is not closed after reading, since it's an io.Reader and not
// an io.ReadCloser. In the event of error, the state that the source reader
// will be left in is undefined.
func Read(r io.Reader) (*Doc, error) {
func Read(r io.Reader) (*Object, error) {
tree, err := parse(r)
if err != nil {
return nil, err
@ -129,22 +129,22 @@ func Read(r io.Reader) (*Doc, error) {
if _, err := tree.eval(ctx); err != nil {
return nil, fmt.Errorf("eval error: %s\n", err)
}
return &Doc{items: ctx.public}, nil
return &Object{items: ctx.public}, nil
}
// Reads a moon document from a string. This is purely a convenience method;
// Reads a moon object from a string. This is purely a convenience method;
// all it does is create a buffer and call the moon.Read function.
func ReadString(source string) (*Doc, error) {
func ReadString(source string) (*Object, error) {
return Read(strings.NewReader(source))
}
// Reads a moon document from a slice of bytes. This is purely a concenience
// Reads a moon object from a slice of bytes. This is purely a concenience
// method; like ReadString, it simply creates a buffer and calls moon.Read
func ReadBytes(b []byte) (*Doc, error) {
func ReadBytes(b []byte) (*Object, error) {
return Read(bytes.NewBuffer(b))
}
func ReadFile(path string) (*Doc, error) {
func ReadFile(path string) (*Object, error) {
f, err := os.Open(path)
if err != nil {
return nil, err

Loading…
Cancel
Save