structomap

package module
v0.6.2 Latest Latest
Warning

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

Go to latest
Published: May 16, 2019 License: MIT Imports: 4 Imported by: 5

README

structomap Build Status Coverage Status GoDoc

This package helps you to transform your struct into map easily. It provides a structomap.Serializer interface implemented by the structomap.Base type which contains chainable function to add, remove or modify fields. The struct is transformed to a map[string]interface{} using the Transform(entity interface{}) method. It is then up to you to encode the result in JSON, XML or whatever you like.

Here is an example.

import "github.com/danhper/structomap"

type User struct {
    ID        int
    Email     string
    HideEmail bool
    FirstName string
    LastName  string
    CreatedAt time.Time
    UpdatedAt time.Time
}

currentTime := time.Date(2015, 05, 13, 15, 30, 0, 0, time.UTC)

user := User{
    ID: 1, Email: "x@example.com", FirstName: "Foo", LastName:  "Bar",
    HideEmail: true, CreatedAt: currentTime, UpdatedAt: currentTime,
}
userSerializer := structomap.New().
              UseSnakeCase().
              Pick("ID", "FirstName", "LastName", "Email").
              PickFunc(func(t interface{}) interface{} {
                  return t.(time.Time).Format(time.RFC3339)
              }, "CreatedAt", "UpdatedAt").
              OmitIf(func(u interface{}) bool {
                  return u.(User).HideEmail
              }, "Email").
              Add("CurrentTime", time.Date(2015, 5, 15, 17, 41, 0, 0, time.UTC)).
              AddFunc("FullName", func(u interface{}) interface{} {
                  return u.(User).FirstName + " " + u.(User).LastName
              })

userMap := userSerializer.Transform(user)
str, _ := json.MarshalIndent(userMap, "", "  ")
fmt.Println(string(str))

will give:

{
  "created_at": "2015-05-13T15:30:00Z",
  "current_time": "2015-05-15T17:41:00Z",
  "first_name": "Foo",
  "full_name": "Foo Bar",
  "id": 1,
  "last_name": "Bar",
  "updated_at": "2015-05-13T15:30:00Z"
}

Working with slices and arrays

You can also use structomap to transform slices and arrays, it will be applied to all elements. The only thing to do is to call TransformArray(entities) on a slice or an array. As TransformArray expects an interface{}, but in fact really wants a slice or an array, a second error argument is returned. If you do not want it, you can use MustTransformArray, which will panic instead of returning an error.

Here in an example reusing the above serializer.

otherUser := User{ID: 2, FirstName: "Ping", LastName: "Pong", CreatedAt: createdAt, UpdatedAt: createdAt}
users := []User{user, otherUser}
result, _ := userSerializer.TransformArray(users)
str, _ := json.MarshalIndent(result, "", "  ")
fmt.Println(string(str))

This will give:

[
  {
    "created_at": "2015-05-13T15:30:00Z",
    "current_time": "2015-05-15T17:41:00Z",
    "first_name": "Foo",
    "full_name": "Foo Bar",
    "id": 1,
    "last_name": "Bar",
    "updated_at": "2015-05-13T15:30:00Z"
  },
  {
    "created_at": "2015-05-13T15:30:00Z",
    "current_time": "2015-05-15T17:41:00Z",
    "email": "",
    "first_name": "Ping",
    "full_name": "Ping Pong",
    "id": 2,
    "last_name": "Pong",
    "updated_at": "2015-05-13T15:30:00Z"
  }
]

Choosing a key format

You can set the key format for the output map using UseSnakeCase(), UsePascalCase() or UseCamelCase() on the serializer object. You can also set the default case for all new serializers by using structomap.SetDefaultCase(structomap.SnakeCase) (structomap.CamelCase and structomap.PascalCase are also available). The init() function would be a good place to set this.

Building your own serializer

With structomap.Base as a base, you can easily build your serializer.

type UserSerializer struct {
  *structomap.Base
}

func NewUserSerializer() *UserSerializer {
  u := &UserSerializer{structomap.New()}
  u.Pick("ID", "CreatedAt", "UpdatedAt", "DeletedAt")
  return u
}

func (u *UserSerializer) WithPrivateInfo() *UserSerializer {
  u.Pick("Email")
  return u
}

userMap := NewUserSerializer().WithPrivateInfo().Transform(user)

Note that the u.Pick, and all other methods do modify the serializer, they do not return a new serializer each time. This is why it works even when ignoring u.Pick return value.

License

This is released under the MIT license. See the LICENSE file for more information.

Godoc

The full documentation is available at https://godoc.org/github.com/danhper/structomap.

Documentation

Overview

Package structomap contains

Index

Examples

Constants

View Source
const (
	// NotSet uses the original case for keys
	NotSet KeyCase = iota

	// CamelCase uses camelCase keys
	CamelCase = iota

	// PascalCase Uses PascalCase keys
	PascalCase = iota

	// SnakeCase uses snake_case keys
	SnakeCase = iota
)

Variables

This section is empty.

Functions

func SetDefaultCase added in v0.6.2

func SetDefaultCase(caseType KeyCase)

SetDefaultCase set the default key case (snake_case, camelCase or PascalCase) for all new serializers

Types

type Base added in v0.6.2

type Base struct {
	// contains filtered or unexported fields
}

Base is a basic implementation of Serializer

func New

func New() *Base

New creates a new serializer

func (*Base) Add added in v0.6.2

func (b *Base) Add(key string, value interface{}) Serializer

Add adds a custom field to the result

func (*Base) AddFunc added in v0.6.2

func (b *Base) AddFunc(key string, f ValueConverter) Serializer

AddFunc adds a computed custom field to the result

func (*Base) AddFuncIf added in v0.6.2

func (b *Base) AddFuncIf(p Predicate, key string, f ValueConverter) Serializer

AddFuncIf adds a computed custom field to the result if the Predicate returns true

func (*Base) AddIf added in v0.6.2

func (b *Base) AddIf(p Predicate, key string, value interface{}) Serializer

AddIf adds a custom field to the result if the Predicate returns true

func (*Base) ConvertKeys added in v0.6.2

func (b *Base) ConvertKeys(keyConverter KeyConverter) Serializer

ConvertKeys converts all the keys using the given converter

func (*Base) MustTransformArray added in v0.6.2

func (b *Base) MustTransformArray(entities interface{}) []map[string]interface{}

MustTransformArray transforms the entities into a []map[string]interface{} array ready to be serialized. Panics if entities is not a slice or an array

func (*Base) Omit added in v0.6.2

func (b *Base) Omit(keys ...string) Serializer

Omit omits the given fields from the result

func (*Base) OmitIf added in v0.6.2

func (b *Base) OmitIf(p Predicate, keys ...string) Serializer

OmitIf omits the given fields from the result if the Predicate returns true

func (*Base) Pick added in v0.6.2

func (b *Base) Pick(keys ...string) Serializer

Pick adds the given fields to the result

func (*Base) PickAll added in v0.6.2

func (b *Base) PickAll() Serializer

PickAll adds all the exported fields to the result

func (*Base) PickFunc added in v0.6.2

func (b *Base) PickFunc(converter ValueConverter, keys ...string) Serializer

PickFunc adds the given fields to the result after applying the converter

func (*Base) PickFuncIf added in v0.6.2

func (b *Base) PickFuncIf(p Predicate, converter ValueConverter, keys ...string) Serializer

PickFuncIf adds the given fields to the result after applying the converter if the predicate returns true

func (*Base) PickIf added in v0.6.2

func (b *Base) PickIf(p Predicate, keys ...string) Serializer

PickIf adds the given fields to the result if the Predicate returns true

func (*Base) Transform added in v0.6.2

func (b *Base) Transform(entity interface{}) map[string]interface{}

Transform transforms the entity into a map[string]interface{} ready to be serialized

func (*Base) TransformArray added in v0.6.2

func (b *Base) TransformArray(entities interface{}) ([]map[string]interface{}, error)

TransformArray transforms the entities into a []map[string]interface{} array ready to be serialized. Entities must be a slice or an array

func (*Base) UseCamelCase added in v0.6.2

func (b *Base) UseCamelCase() Serializer

UseCamelCase uses camelCase keys for the serializer

func (*Base) UsePascalCase added in v0.6.2

func (b *Base) UsePascalCase() Serializer

UsePascalCase uses PascalCase keys for the serializer

func (*Base) UseSnakeCase added in v0.6.2

func (b *Base) UseSnakeCase() Serializer

UseSnakeCase uses snake_case keys for the serializer

type KeyCase added in v0.6.2

type KeyCase int

KeyCase represenets the word case of the output keys

type KeyConverter added in v0.6.2

type KeyConverter func(string) string

KeyConverter is an alias for func(string) string used to transform keys

type Predicate added in v0.6.2

type Predicate func(interface{}) bool

Predicate is an alias for func(interface{}) bool used to test for inclusion

type Serializer

type Serializer interface {
	Transform(entity interface{}) map[string]interface{}
	TransformArray(entities interface{}) ([]map[string]interface{}, error)
	MustTransformArray(entities interface{}) []map[string]interface{}
	ConvertKeys(keyConverter KeyConverter) Serializer
	UseSnakeCase() Serializer
	UseCamelCase() Serializer
	UsePascalCase() Serializer
	PickAll() Serializer
	Pick(keys ...string) Serializer
	PickIf(predicate Predicate, keys ...string) Serializer
	PickFunc(converter ValueConverter, keys ...string) Serializer
	PickFuncIf(predicate Predicate, converter ValueConverter, keys ...string) Serializer
	Omit(keys ...string) Serializer
	OmitIf(predicate Predicate, keys ...string) Serializer
	Add(key string, value interface{}) Serializer
	AddIf(predicate Predicate, key string, value interface{}) Serializer
	AddFunc(key string, converter ValueConverter) Serializer
	AddFuncIf(predicate Predicate, key string, converter ValueConverter) Serializer
}

Serializer is the base interface containing all serialization methods

Example
userMap := exampleSerializer.Transform(user)
str, _ := json.MarshalIndent(userMap, "", "  ")
fmt.Println(string(str))
Output:

{
  "created_at": "2015-05-13T15:30:00Z",
  "current_time": "2015-05-15T17:41:00Z",
  "first_name": "Foo",
  "full_name": "Foo Bar",
  "id": 1,
  "last_name": "Bar",
  "updated_at": "2015-05-13T15:30:00Z"
}

type ValueConverter added in v0.6.2

type ValueConverter func(interface{}) interface{}

ValueConverter is an alias for func(interface{}) interface{} used to transform values

Jump to

Keyboard shortcuts

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