hummus

package module
v0.0.0-...-ff6495d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 23, 2018 License: MIT Imports: 8 Imported by: 0

README

hummus

A concise way to declare structs and marshal them into JSON in Go.

Making nested structs/arrays in order to marshal JSON from objects can be such a pain sometimes, can't it? Especially when you are cherry-picking fields from one flat JSON message and trying to output them into another complex JSON message.

Well, along comes hummus which makes this super-duper easy. The biggest win, I feel, is that you can have all your nesting information in the same struct. Creating nested arrays and/or objects is a simple matter of using dots (.) or square brackets ([]) in your tags.

How to install

go get github.com/aditya87/hummus
Fetch dependencies
go get github.com/Jeffail/gabs
For testing
go get github.com/onsi/ginkgo/ginkgo
go get github.com/onsi/gomega

How to use

Marshalling JSON
...
type Info struct {
  Company           string `hummus:"company"`
	Address           string `hummus:"address"`
	Brand0Name        string `hummus:"brands[0].name"`
	Brand0Flavor      string `hummus:"brands[0].flavor"`
	Brand0Store0Name  string `hummus:"brands[0].stores[0].name"`
	Brand0Store0Price int    `hummus:"brands[0].stores[0].price,omitempty"`
	Brand0Store1Name  string `hummus:"brands[0].stores[1].name"`
	Brand0Store1Price int    `hummus:"brands[0].stores[1].price,omitempty"`
}

func main() {
  info := Info{
		Company:           "hello foods",
		Address:           "338 New St",
		Brand0Name:        "sabra",
		Brand0Flavor:      "jalapeno",
		Brand0Store0Name:  "safeway",
		Brand0Store0Price: 5,
		Brand0Store1Name:  "wholefoods",
		Brand0Store1Price: 10,
	}

	jsonOutput, err := hummus.Marshal(info)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(jsonOutput))
}

Gives us:

{
  "company": "hello foods",
  "address": "338 New St",
  "brands": [
    {
      "flavor": "jalapeno",
      "name": "sabra",
      "stores": [
        {
          "name": "safeway",
          "price": 5
        },
        {
          "name": "wholefoods",
          "price": 10
        }
      ]
    }
  ]
}
Translating one type of message into another
type Info struct {
	Name   string `json:"name" hummus:"name"`
	Flavor string `json:"flavor" hummus:"type"`

	MainSupplierName     string `json:"main_supplier_name" hummus:"suppliers[0].name"`
	MainSupplierLocation string `json:"main_supplier_location" hummus:"suppliers[0].location"`

	BackupSupplierName     string `json:"backup_supplier_name" hummus:"suppliers[1].name"`
	BackupSupplierLocation string `json:"backup_supplier_location" hummus:"suppliers[1].location"`
}

func main() {
	inputJSON := `{
		"name": "sabra",
		"flavor": "jalapeno",
		"main_supplier_name": "Hipster Foods",
		"main_supplier_location": "CO",
		"backup_supplier_name": "Good Foods",
		"backup_supplier_location": "CA"
	}`

	var input Info
	err := json.Unmarshal([]byte(inputJSON), &input)
	if err != nil {
		panic(err)
	}

	jsonOutput, err := hummus.Marshal(input)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(jsonOutput))
}

Gives us:

{
  "name": "sabra",
  "type": "jalapeno",
  "suppliers": [
    {
      "location": "CO",
      "name": "Hipster Foods"
    },
    {
      "location": "CA",
      "name": "Good Foods"
    }
  ]
}
Special cases
Escaping dots

Sometimes, you want to not interpret the dots in a JSON tag as hierarchical keys, instead you just want them to get interpreted as a flat key like so:

{
  "properties.name": "value"
}

Hummus offers you the ability to escape dots. Simply replace dots with hashtags in the struct tags:

...
type S struct {
	V string `hummus:"properties#name"`
}

func main() {
	s := S{
		V: "value",
	}

	jsonOutput, err := hummus.Marshal(s)
	if err != nil {
		panic(err)
	}

	fmt.Println(string(jsonOutput))
}

This gives us:

{
  "properties.name": "value"
}

Which is the desired result.

Notes

  1. Also provided an omitempty option to ignore empty fields, just like the encoding/json library. e.g.:
type foo struct {
  bar string `hummus:"bar,omitempty"`
}
  1. Leverages reflect for dynamic struct interpretation and gabs for dynamic JSON generation.

Contributing

PRs are welcome. Make sure unit tests are run. To do so, firstly install the ginkgo and gomega libraries as described in the "fetch dependencies" section above. Then, simply run:

ginkgo -r .

In the main directory.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Marshal

func Marshal(input interface{}) ([]byte, error)

Types

This section is empty.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL