Basics working
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..185aa0b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,10 @@
+# mapstructure
+
+mapstructure is a Go library for converting generic map values to structures
+and vice versa, while providing helpful error handling.
+
+This library is most useful when decoding values from some data stream (JSON,
+Gob, etc.) where you don't _quite_ know the structure of the underlying data
+until you read a part of it. You can therefore read a `map[string]interface{}`
+and use this library to decode it into the proper underlying native Go
+structure.
diff --git a/mapstructure.go b/mapstructure.go
new file mode 100644
index 0000000..eaf505d
--- /dev/null
+++ b/mapstructure.go
@@ -0,0 +1,62 @@
+package mapstructure
+
+import (
+	"errors"
+	"reflect"
+	"strings"
+)
+
+// MapToStruct takes a map and uses reflection to convert it into the
+// given Go native structure. val must be a pointer to a struct.
+func MapToStruct(m map[string]interface{}, rawVal interface{}) error {
+	val := reflect.ValueOf(rawVal).Elem()
+	if !val.CanAddr() {
+		return errors.New("val must be addressable (a pointer)")
+	}
+
+	if val.Kind() != reflect.Struct {
+		return errors.New("val must be an addressable struct")
+	}
+
+	valType := val.Type()
+
+	for i := 0; i < valType.NumField(); i++ {
+		fieldType := valType.Field(i)
+		fieldName := fieldType.Name
+
+		rawMapVal, ok := m[fieldName]
+		if !ok {
+			// Do a slower search by iterating over each key and
+			// doing case-insensitive search.
+			for mK, mV := range m {
+				if strings.EqualFold(mK, fieldName) {
+					rawMapVal = mV
+					break
+				}
+			}
+
+			if rawMapVal == nil {
+				// There was no matching key in the map for the value in
+				// the struct. Just ignore.
+				continue
+			}
+		}
+
+		field := val.Field(i)
+		if !field.IsValid() {
+			// This should never happen
+			panic("field is not valid")
+		}
+
+		mapVal := reflect.ValueOf(rawMapVal)
+		if !mapVal.IsValid() {
+			// This should never happen because we got the value out
+			// of the map.
+			panic("map value is not valid")
+		}
+
+		field.Set(mapVal)
+	}
+
+	return nil
+}
diff --git a/mapstructure_test.go b/mapstructure_test.go
new file mode 100644
index 0000000..593ba06
--- /dev/null
+++ b/mapstructure_test.go
@@ -0,0 +1,38 @@
+package mapstructure
+
+import "testing"
+
+type Basic struct {
+	Vstring string
+	Vint int
+	Vbool bool
+}
+
+func TestBasicTypes(t *testing.T) {
+	t.Parallel()
+
+	input := map[string]interface{}{
+		"vstring": "foo",
+		"vint": 42,
+		"vbool": true,
+	}
+
+	var result Basic
+	err := MapToStruct(input, &result)
+	if err != nil {
+		t.Errorf("got an err: %s", err.Error())
+		t.FailNow()
+	}
+
+	if result.Vstring != "foo" {
+		t.Errorf("vstring value should be 'foo': %#v", result.Vstring)
+	}
+
+	if result.Vint != 42 {
+		t.Errorf("vint value should be 42: %#v", result.Vint)
+	}
+
+	if result.Vbool != true {
+		t.Errorf("vbool value should be true: %#v", result.Vbool)
+	}
+}