Skip to content

Commit

Permalink
Most basic marshal
Browse files Browse the repository at this point in the history
  • Loading branch information
blgm committed May 4, 2020
1 parent 00ef17b commit 91f2cae
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea
vendor
go.sum
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# JSONry

A Go module for converting between a Go `struct` and JSON.

JSONry is being extracted from the [Cloud Foundry CLI](https://github.com/cloudfoundry/cli) project. It exists to make it easier
to define the translation between complex JSON data and Go structures.
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module code.cloudfoundry.org/jsonry

go 1.13

require (
github.com/onsi/ginkgo v1.12.0
github.com/onsi/gomega v1.9.0
)
13 changes: 13 additions & 0 deletions jsonry_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package jsonry_test

import (
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

func TestJSONry(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "JSONry Suite")
}
38 changes: 38 additions & 0 deletions marshal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package jsonry

import (
"encoding/json"
"errors"
"reflect"
)

func Marshal(input interface{}) ([]byte, error) {
i := reflect.ValueOf(input)

if i.Kind()==reflect.Ptr {
i = i.Elem()
}

if i.Kind() != reflect.Struct {
return nil, errors.New("the input must be a struct")
}

m, err := marshal(i)
if err != nil {
return nil, err
}

return json.Marshal(m)
}

func marshal(in reflect.Value) (map[string]interface{}, error) {
out := make(map[string]interface{})

t := in.Type()
for i := 0; i<t.NumField(); i++ {
f := t.Field(i)
out[f.Name] = in.Field(i).Interface()
}

return out, nil
}
44 changes: 44 additions & 0 deletions marshal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package jsonry_test

import (
"code.cloudfoundry.org/jsonry"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)

var _ = Describe("Marshal", func() {
Describe("basic types", func() {
It("basic", func() {
type t struct{A string}
out, err := jsonry.Marshal(t{A:"hello"})
Expect(err).NotTo(HaveOccurred())
Expect(out).To(MatchJSON(`{"A":"hello"}`))
})
})

Describe("inputs", func() {
It("accept a struct", func() {
var s struct{}
_, err := jsonry.Marshal(s)
Expect(err).NotTo(HaveOccurred())
})

It("accept a struct pointer", func() {
var s struct{}
_, err := jsonry.Marshal(&s)
Expect(err).NotTo(HaveOccurred())
})

It("rejects a non-struct value", func() {
_, err := jsonry.Marshal(42)
Expect(err).To(MatchError("the input must be a struct"))
})

It("rejects a nil pointer", func() {
type s struct{}
var sp *s
_, err := jsonry.Marshal(sp)
Expect(err).To(MatchError("the input must be a struct"))
})
})
})

0 comments on commit 91f2cae

Please sign in to comment.