Code Monkey home page Code Monkey logo

consul-decoder's Introduction

License: MIT Go Report Card GoDoc Build Status

Note - The latest version supports only go 1.11 or later since swithcing to go modules. For older versions of go, pin to the v0.2.3 tag.

Package decoder - this unmarshals or decodes values from a consul KV store into a struct. The following types are supported:

  • integer (int/int8/int16/int32/int64)

  • unsigned (uint/uint8/uint16/uint32/uint64)

  • float (float64/float32)

  • bool

  • time.Duration

  • net.IP

  • net.IPMask

  • struct - nested struct by default implies a consul folder with the same name. if the tag modifier "json" is encountered, then the value of in the KV is unmarshaled as json using json.Unmarshal

  • slice - the type can be most of the supported types, except another slice.

  • map - the key must be a string, the value can be anything but another map.

  • encoding.TextUnmarshaler - any type that implements this will have its UnmarshalText() method called.

Struct tags

By default, the decoder packages looks for the struct tag "decoder". However, this can be overridden inside the Decoder struct as shown below. For the purposes of examples, we'll stick with the default "decoder" tag. By default, in the absence of a decoder tag, it will look for a consul key name with the same name as the struct field. Only exported struct fields are considered. The name comparison is case-insensitive by default, but this is configurable in the Decoder struct. the tag "-" indicates to skip the field. The modifier ",json" appended to the end signals that the value is to be interpreted as json and unmarshaled rather than interpreted. Similarly, the modififier ",csv" allows comma separated values to be read into a slice, and ",ssv" allows space separated values to be read intoa slice. For csv and ssv, slices of string, numeric and boolean are supported.

    struct Foo {

        // populate the value from key "whatever" into FooField1
        FooField1 string `decoder:"whatever"`

        // skip populating FooField2, "-" signals skip
        FooField2 string `decoder:"-"`

        // this looks for a folder named FooField3
        // and maps keys inside to the keys / values of the map.  string
        // is the only valid key type, though the map value can be most any
        // of the other types supported by this package.  Notable exception
        // map, as nested maps are not allowed.  You can, however, have a
        // map[string]SomeStruct.
        FooField3 map[string]string

        // this looks for a folder named FooField4 (case insensitive)
        // this is similar to the map example above, but it ignores the keys
        // inside and maps the values in-order into the slice.  nested slices
        // are not allowed, i.e., [][]string.
        FooField4 []string

        // this interprets the value of foofield5 as json data and
        // will send it to json.Unmarshal from encoding/json package.
        FooField5 *SomeStruct `decoder:"foofield5,json"`

        // this expects there to be a consul folder foofield6 and that the
        // keys within will correspond to the fields inside SomeStruct type.
        FooField6 *SomeStruct `decoder:"foofield6"`

        // It is possible to specify arbitrarily nested values by giving
        // the path in the struct tag.
        FooField7 string `decoder:"arbitrarily/nested/key"`

        // Comma separated values are supported.  This uses the encoding/csv
        // package, so all variations supported by it are supported here.
        FooField8 []string `decoder:",csv"`

        // Space separated values are supported.  This uses strings.Fields
        // for parsing, so see that documentation for information.
        FooField9 []string `decoder:",ssv"`
}

consul-decoder's People

Contributors

dcarbone avatar nathanejohnson avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

Forkers

ppai-plivo

consul-decoder's Issues

Re-using struct causes out of range panic

Given:

type (
    ChildPrototype struct {
        Name string
    }
    Parent struct {
        Child1 ChildPrototype
        Child2 ChildPrototype
    }
)

Results in (pulled from test I've created):

panic: reflect: Field index out of range [recovered]
        panic: reflect: Field index out of range

goroutine 4 [running]:
testing.tRunner.func1(0xc000116200)
        testing/testing.go:792 +0x6a7
panic(0x157c060, 0x168eb40)
       runtime/panic.go:513 +0x1b9
reflect.Value.Field(0x15bbe80, 0xc0004901a0, 0x199, 0x18, 0x15bbe80, 0xc0004901a0, 0x199)
       reflect/value.go:786 +0x2bc
github.com/myENA/consul-decoder.(*Decoder).allocAssign(0xc0003b58e0, 0xc0004713c0, 0xc000255980, 0xc0003b52f0, 0x1601e80, 0xc000490000, 0x199, 0xc000465520, 0x8, 0x0, ...)
        src/github.com/myENA/consul-decoder/decoder.go:474 +0x3f3
github.com/myENA/consul-decoder.(*Decoder).Unmarshal(0xc0003b58e0, 0xc000465520, 0x8, 0xc0002383b0, 0xa, 0xc, 0x15675c0, 0xc000490000, 0x0, 0x0)
        src/github.com/myENA/consul-decoder/decoder.go:444 +0x4f8
github.com/myENA/consul-decoder.(*encoderTestSuite).TestUnmarshal(0xc000087020)
        src/github.com/myENA/consul-decoder/decoder_test.go:239 +0x6d5
reflect.Value.call(0xc0003acd20, 0xc000474068, 0x13, 0x160b987, 0x4, 0xc0003b5f00, 0x1, 0x1, 0xc0003b5de8, 0x1063592, ...)
        src/reflect/value.go:447 +0x62c
reflect.Value.Call(0xc0003acd20, 0xc000474068, 0x13, 0xc0003b5f00, 0x1, 0x1, 0x15473e3, 0xd, 0x0)
        reflect/value.go:308 +0xc1
github.com/myENA/consul-decoder/vendor/github.com/stretchr/testify/suite.Run.func2(0xc000116200)
        src/github.com/myENA/consul-decoder/vendor/github.com/stretchr/testify/suite/suite.go:102 +0x2d0
testing.tRunner(0xc000116200, 0xc00040e080)
        testing/testing.go:827 +0x163
created by testing.(*T).Run
       testing/testing.go:878 +0x651
exit status 2
FAIL    github.com/myENA/consul-decoder 2.004s

Bug: Keys that contain JSON cannot be unmarshaled into structs

With the following key setup:

test/
 |- string = "string"
 |- Value = `{"field1":"value","field2": {"map1":"value1","map2":["value2"]}}`

and the following structs:

type (
    TestNestedJSONStructValue struct {
	Field1 string
	Field2 map[string]interface{}
    }
    TestNestedJSONStruct struct {
	String string
	Value  TestNestedJSONStructValue `decoder:"Value,json"`
    }
    TestStruct struct {
        JSONStruct TestNestedJSONStruct `decoder:"test"`
    }
)

the current unmarshal implementation fails silently to populate TestStruct.Value.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.