From 60d5ee4dc86e8c5b3dfb7cb2706dac934e47a23d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Carlos=20Nieto?= <xiam@menteslibres.org>
Date: Sun, 8 Jul 2012 17:12:20 -0500
Subject: [PATCH] Publishing gosexy/yaml.

---
 README.md                | 20 ++++++++++
 yaml/README.md           | 24 ++++++++++++
 yaml/examples/go/main.go |  9 +++++
 yaml/yaml.go             | 80 +++++++++++++++++++++++++++-------------
 yaml/yaml_test.go        | 14 +++----
 5 files changed, 112 insertions(+), 35 deletions(-)
 create mode 100644 README.md
 create mode 100644 yaml/README.md
 create mode 100644 yaml/examples/go/main.go

diff --git a/README.md b/README.md
new file mode 100644
index 00000000..6b96b199
--- /dev/null
+++ b/README.md
@@ -0,0 +1,20 @@
+# What is gosexy?
+
+gosexy is a general purpose framework for Go that provides sugar methods, types and abstractions.
+
+## Installing gosexy
+
+Use the command line:
+
+  $ go get github.com/xiam/gosexy
+
+## Sugar types
+
+``Tuple`` is a shortcut for ``map[string]interface{}`` (generic dictionaries).
+
+``List`` is a shortcut for ``[]interface{}`` (generic arrays).
+
+## Sugar abstractions
+
+* [gosexy/yaml](https://github.com/xiam/gosexy/tree/master/yaml) - A wrapper of [goyaml](http://launchpad.net/goyaml) for working with [YAML](http://www.yaml.org) formatted files.
+
diff --git a/yaml/README.md b/yaml/README.md
new file mode 100644
index 00000000..c528066f
--- /dev/null
+++ b/yaml/README.md
@@ -0,0 +1,24 @@
+# gosexy/yaml
+
+This package is a wrapper of [goyaml](http://launchpad.net/goyaml) that provides methods for loading, reading and writing to and from [YAML](http://www.yaml.org/) formatted files.
+
+## Installation
+
+	$ go get github.com/xiam/gosexy/yaml
+
+## Usage
+
+	package main
+
+	import "github.com/xiam/gosexy/yaml"
+
+	func main() {
+		settings := yaml.New()
+		defer settings.Write("test.yaml")
+		settings.Set("success", true)
+	}
+
+## Documentation
+
+	$ go doc github.com/xiam/gosexy/yaml
+
diff --git a/yaml/examples/go/main.go b/yaml/examples/go/main.go
new file mode 100644
index 00000000..26d8f8b7
--- /dev/null
+++ b/yaml/examples/go/main.go
@@ -0,0 +1,9 @@
+package main
+
+import "github.com/xiam/gosexy/yaml"
+
+func main() {
+	settings := yaml.New()
+	defer settings.Write("test.yaml")
+	settings.Set("success", true)
+}
diff --git a/yaml/yaml.go b/yaml/yaml.go
index 77a701fb..9bf1acba 100644
--- a/yaml/yaml.go
+++ b/yaml/yaml.go
@@ -24,27 +24,44 @@
 package yaml
 
 import (
-	"github.com/xiam/gosexy"
+	"fmt"
+	. "github.com/xiam/gosexy"
 	"launchpad.net/goyaml"
 	"os"
 	"strings"
 )
 
-type Storage struct {
-	storage *gosexy.Tuple
+type Yaml struct {
+	file   string
+	values *Tuple
 }
 
-func NewYAML() *Storage {
-	c := &Storage{}
-	return c
+// Creates and returns a new YAML structure.
+func New() *Yaml {
+	yaml := &Yaml{}
+	yaml.values = &Tuple{}
+	return yaml
 }
 
-func (c *Storage) Get(path string, def interface{}) interface{} {
-	var p gosexy.Tuple
+// Creates and returns a YAML structure from a file.
+func Open(file string) *Yaml {
+	yaml := New()
+	yaml.file = file
+	yaml.Read(yaml.file)
+	return yaml
+}
+
+// Returns a YAML setting (or nil if the referred name does not exists). Read nested values by using a dot (.) between labels.
+//
+// Example:
+//
+//	yaml.Get("foo.bar")
+func (y *Yaml) Get(path string, def interface{}) interface{} {
+	var p Tuple
 
 	path = strings.ToLower(path)
 
-	p = *c.storage
+	p = *y.values
 
 	chunks := strings.Split(path, ".")
 
@@ -62,9 +79,9 @@ func (c *Storage) Get(path string, def interface{}) interface{} {
 
 			if ok == true {
 				switch value.(type) {
-				case gosexy.Tuple:
+				case Tuple:
 					{
-						p = value.(gosexy.Tuple)
+						p = value.(Tuple)
 					}
 				default:
 					{
@@ -81,12 +98,13 @@ func (c *Storage) Get(path string, def interface{}) interface{} {
 	return def
 }
 
-func (c *Storage) Set(path string, value interface{}) {
-	var p gosexy.Tuple
+// Sets a YAML setting, use dots (.) to nest values inside values.
+func (y *Yaml) Set(path string, value interface{}) {
+	var p Tuple
 
 	path = strings.ToLower(path)
 
-	p = *c.storage
+	p = *y.values
 
 	chunks := strings.Split(path, ".")
 
@@ -103,27 +121,27 @@ func (c *Storage) Set(path string, value interface{}) {
 			// Searching.
 			if ok == true {
 				switch current.(type) {
-				case gosexy.Tuple:
+				case Tuple:
 					{
 						// Just skip.
 					}
 				default:
 					{
 						delete(p, chunks[i])
-						p[chunks[i]] = gosexy.Tuple{}
+						p[chunks[i]] = Tuple{}
 					}
 				}
 			} else {
-				p[chunks[i]] = gosexy.Tuple{}
+				p[chunks[i]] = Tuple{}
 			}
 
-			p = p[chunks[i]].(gosexy.Tuple)
+			p = p[chunks[i]].(Tuple)
 		}
 	}
 
 }
 
-func (c *Storage) Map(data interface{}, parent *gosexy.Tuple) {
+func (y *Yaml) mapValues(data interface{}, parent *Tuple) {
 
 	var name string
 
@@ -153,8 +171,8 @@ func (c *Storage) Map(data interface{}, parent *gosexy.Tuple) {
 			}
 		case interface{}:
 			{
-				values := &gosexy.Tuple{}
-				c.Map(value, values)
+				values := &Tuple{}
+				y.mapValues(value, values)
 				(*parent)[name] = *values
 			}
 		}
@@ -163,9 +181,19 @@ func (c *Storage) Map(data interface{}, parent *gosexy.Tuple) {
 
 }
 
-func (c *Storage) Write(filename string) {
+// Saves changes made to the latest Open()'ed YAML file.
+func (y *Yaml) Save() {
+	if y.file != "" {
+		y.Write(y.file)
+	} else {
+		panic(fmt.Errorf("No file specified."))
+	}
+}
+
+// Writes the current YAML structure into an arbitrary file.
+func (y *Yaml) Write(filename string) {
 
-	out, err := goyaml.Marshal(c.storage)
+	out, err := goyaml.Marshal(y.values)
 	if err != nil {
 		panic(err)
 	}
@@ -179,7 +207,8 @@ func (c *Storage) Write(filename string) {
 	fp.Write(out)
 }
 
-func (c *Storage) Read(filename string) {
+// Reads a YAML file and stores it into the current YAML structure.
+func (y *Yaml) Read(filename string) {
 	var err error
 	var data interface{}
 
@@ -206,8 +235,7 @@ func (c *Storage) Read(filename string) {
 
 	if err == nil {
 
-		c.storage = &gosexy.Tuple{}
-		c.Map(data, c.storage)
+		y.mapValues(data, y.values)
 
 	} else {
 
diff --git a/yaml/yaml_test.go b/yaml/yaml_test.go
index e708ea82..f9ec2b01 100644
--- a/yaml/yaml_test.go
+++ b/yaml/yaml_test.go
@@ -3,13 +3,11 @@ package yaml
 import "testing"
 
 func TestRead(t *testing.T) {
-	settings := NewYAML()
-	settings.Read("examples/input/settings.yaml")
+	Open("examples/input/settings.yaml")
 }
 
 func TestGet(t *testing.T) {
-	settings := NewYAML()
-	settings.Read("examples/input/settings.yaml")
+	settings := Open("examples/input/settings.yaml")
 
 	test1 := "Hello World!"
 	val1 := settings.Get("test_string", nil).(string)
@@ -42,8 +40,7 @@ func TestGet(t *testing.T) {
 }
 
 func TestSet(t *testing.T) {
-	settings := NewYAML()
-	settings.Read("examples/input/settings.yaml")
+	settings := Open("examples/input/settings.yaml")
 
 	settings.Set("test_map.element_3.test_bool", true)
 
@@ -57,10 +54,9 @@ func TestSet(t *testing.T) {
 }
 
 func TestWrite(t *testing.T) {
-	settings := NewYAML()
-	settings.Read("examples/input/settings.yaml")
+	settings := New()
+	defer settings.Write("examples/input/settings2.yaml")
 
 	settings.Set("test_map.element_3.test_bool", true)
 
-	settings.Write("examples/output/settings.yaml")
 }
-- 
GitLab