Skip to content

Commit

Permalink
Marshal map[string]string
Browse files Browse the repository at this point in the history
  • Loading branch information
Songmu committed Jul 10, 2016
1 parent 90d4931 commit b7f2c59
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
69 changes: 69 additions & 0 deletions encode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package ltsv

import (
"fmt"
"reflect"
"strings"
)

type Marshaler interface {
MarshalLTSV([]byte) error
}

// MarshalError is an error type for Marshal()
type MarshalError map[string]error

func (m MarshalError) Error() string {
if len(m) == 0 {
return "(no error)"
}

ee := make([]string, 0, len(m))
for name, err := range m {
ee = append(ee, fmt.Sprintf("field %q: %s", name, err))
}

return strings.Join(ee, "\n")
}

// OfField returns the error correspoinding to a given field
func (m MarshalError) OfField(name string) error {
return m[name]
}

// An MarshalTypeError describes a LTSV value that was
// not appropriate for a value of a specific Go type.
type MarshalTypeError struct {
Value string
Type reflect.Type
}

func (e *MarshalTypeError) Error() string {
return "ltsv: cannot marshal " + e.Value + " into Go value of type " + e.Type.String()
}

func Marshal(v interface{}) ([]byte, error) {
rv := reflect.ValueOf(v)
if rv.Kind() == reflect.Ptr {
rv = rv.Elem()
}
if rv.Kind() != reflect.Struct && rv.Kind() != reflect.Map {
return nil, fmt.Errorf("not a struct/map: %v", v)
}

if rv.Kind() == reflect.Map {
kt := rv.Type().Key()
vt := rv.Type().Elem()
if kt.Kind() != reflect.String || vt.Kind() != reflect.String {
return nil, fmt.Errorf("not a map[string]string")
}

mKeys := rv.MapKeys()
arr := make([]string, len(mKeys), len(mKeys))
for i, k := range mKeys {
arr[i] = k.String() + ":" + rv.MapIndex(k).String()
}
return []byte(strings.Join(arr, "\t")), nil
}
return nil, nil
}
16 changes: 16 additions & 0 deletions encode_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package ltsv

import "testing"

func TestMarshal(t *testing.T) {
data := map[string]string{
"hoge": "fuga",
"piyo": "piyo",
}
expect1 := []byte("hoge:fuga\tpiyo:piyo")
expect2 := []byte("piyo:piyo\thoge:fuga")
r, _ := Marshal(data)
if string(r) != string(expect1) && string(r) != string(expect2) {
t.Errorf("result is not expected: %s", string(r))
}
}

0 comments on commit b7f2c59

Please sign in to comment.