structool

package module
v0.0.0-...-41b1725 Latest Latest
Warning

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

Go to latest
Published: Sep 15, 2023 License: MIT Imports: 7 Imported by: 7

README

structool

A codec for Go structs with support for chainable encoding/decoding hooks.

Features

  1. Provide a uniform codec by combining mapstructure and structs.
  2. Make encoding/decoding hooks chainable.

Installation

$ go get -u github.com/RussellLuo/structool

Why?!

  1. Why to use structs

    mapstructure has limited support for decoding structs into maps (issues/166 and issues/249).

  2. Why to make a fork of fatih/structs

    fatih/structs has been archived, but it does not support encoding hooks yet.

  3. Why chainable hooks may be useful

    Both mapstructure and structs support hooks in the form of a single function. While this keeps the libraries themselves simple, it forces us to couple various conversions together.

    Chainable hooks (like HTTP middlewares), on the other hand, promote separation of concerns, and thus make individual hooks reusable and composable.

Documentation

Check out the Godoc.

License

MIT

Documentation

Overview

Example (Decode)
package main

import (
	"fmt"
	"net"
	"time"

	"github.com/RussellLuo/structool"
)

func main() {
	in := map[string]interface{}{
		"string":   "s",
		"bool":     true,
		"int_str":  "10",
		"int":      1,
		"error":    "oops",
		"time":     "2021-09-29T00:00:00Z",
		"duration": "2s",
		"ip":       "192.168.0.1",
	}
	out := struct {
		String   string        `structool:"string"`
		Bool     bool          `structool:"bool"`
		IntStr   int           `structool:"int_str"`
		Int      int           `structool:"int"`
		Error    error         `structool:"error"`
		Time     time.Time     `structool:"time"`
		Duration time.Duration `structool:"duration"`
		IP       net.IP        `structool:"ip"`
	}{}

	codec := structool.New().DecodeHook(
		structool.DecodeStringToError,
		structool.DecodeStringToTime(time.RFC3339),
		structool.DecodeStringToDuration,
		structool.DecodeStringToIP,
		structool.DecodeStringToNumber,
	)
	if err := codec.Decode(in, &out); err != nil {
		panic(err)
	}

	fmt.Printf("%+v\n", out)

}
Output:

{String:s Bool:true IntStr:10 Int:1 Error:oops Time:2021-09-29 00:00:00 +0000 UTC Duration:2s IP:192.168.0.1}
Example (DecodeField)
package main

import (
	"fmt"
	"time"

	"github.com/RussellLuo/structool"
)

func main() {
	in := "2s"
	var out time.Duration

	codec := structool.New().DecodeHook(structool.DecodeStringToDuration)
	if err := codec.Decode(in, &out); err != nil {
		panic(err)
	}

	fmt.Printf("%#v\n", out)

}
Output:

2000000000
Example (Encode)
package main

import (
	"fmt"
	"net"
	"time"

	"github.com/RussellLuo/structool"
)

func main() {
	in := struct {
		String   string        `structool:"string"`
		Bool     bool          `structool:"bool"`
		Int      int           `structool:"int"`
		Error    error         `structool:"error"`
		Time     time.Time     `structool:"time"`
		Duration time.Duration `structool:"duration"`
		IP       net.IP        `structool:"ip"`
	}{
		String:   "s",
		Bool:     true,
		Int:      1,
		Error:    fmt.Errorf("oops"),
		Time:     time.Date(2021, 9, 29, 0, 0, 0, 0, time.UTC),
		Duration: 2 * time.Second,
		IP:       net.IPv4(192, 168, 0, 1),
	}

	codec := structool.New().EncodeHook(
		structool.EncodeErrorToString,
		structool.EncodeTimeToString(time.RFC3339),
		structool.EncodeDurationToString,
		structool.EncodeIPToString,
	)
	out, err := codec.Encode(in)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%#v\n", out)

}
Output:

map[string]interface {}{"bool":true, "duration":"2s", "error":"oops", "int":1, "ip":"192.168.0.1", "string":"s", "time":"2021-09-29T00:00:00Z"}
Example (EncodeField)
package main

import (
	"fmt"
	"time"

	"github.com/RussellLuo/structool"
)

func main() {
	in := 2 * time.Second

	codec := structool.New().EncodeHook(structool.EncodeDurationToString)
	out, err := codec.Encode(in)
	if err != nil {
		panic(err)
	}

	fmt.Printf("%#v\n", out)

}
Output:

"2s"

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecodeStringToTime

func DecodeStringToTime(layout string) func(DecodeHookFunc) DecodeHookFunc

func EncodeTimeToString

func EncodeTimeToString(layout string) func(EncodeHookFunc) EncodeHookFunc

Types

type Codec

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

func New

func New() *Codec

func (*Codec) Decode

func (c *Codec) Decode(in interface{}, out interface{}) (err error)

func (*Codec) DecodeHook

func (c *Codec) DecodeHook(hooks ...func(DecodeHookFunc) DecodeHookFunc) *Codec

func (*Codec) Encode

func (c *Codec) Encode(in interface{}) (out interface{}, err error)

func (*Codec) EncodeHook

func (c *Codec) EncodeHook(hooks ...func(EncodeHookFunc) EncodeHookFunc) *Codec

func (*Codec) TagName

func (c *Codec) TagName(name string) *Codec

type DecodeHookFunc

type DecodeHookFunc mapstructure.DecodeHookFuncValue

func DecodeStringToDuration

func DecodeStringToDuration(next DecodeHookFunc) DecodeHookFunc

func DecodeStringToError

func DecodeStringToError(next DecodeHookFunc) DecodeHookFunc

func DecodeStringToIP

func DecodeStringToIP(next DecodeHookFunc) DecodeHookFunc

func DecodeStringToNumber

func DecodeStringToNumber(next DecodeHookFunc) DecodeHookFunc

type EncodeHookFunc

type EncodeHookFunc structs.EncodeHookFunc

func EncodeDurationToString

func EncodeDurationToString(next EncodeHookFunc) EncodeHookFunc

func EncodeErrorToString

func EncodeErrorToString(next EncodeHookFunc) EncodeHookFunc

func EncodeIPToString

func EncodeIPToString(next EncodeHookFunc) EncodeHookFunc

func EncodeNumberToString

func EncodeNumberToString(next EncodeHookFunc) EncodeHookFunc

Jump to

Keyboard shortcuts

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