-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
85 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) | ||
} | ||
} |