Code Monkey home page Code Monkey logo

go-defaults's Introduction

go-defaults Build Status GoDoc GitHub release

Enabling stuctures with defaults values using struct tags.

Installation

This is a fork repo. See base repository, refer to:

github.com/mcuadros/go-defaults

The recommended way to install this go-defaults

go get github.com/zhlingbo/go-defaults

Examples

A basic example:

import (
    "fmt"
    "github.com/zhlingbo/go-defaults"
    "time"
)

type ExampleBasic struct {
    Foo bool   `default:"true"` //<-- StructTag with a default key
    Bar string `default:"33"`
    Qux int8
    Dur time.Duration `default:"1m"`
}

func NewExampleBasic() *ExampleBasic {
    example := new(ExampleBasic)
    defaults.SetDefaults(example) //<-- This set the defaults values

    return example
}

...

test := NewExampleBasic()
fmt.Println(test.Foo) //Prints: true
fmt.Println(test.Bar) //Prints: 33
fmt.Println(test.Qux) //Prints:
fmt.Println(test.Dur) //Prints: 1m0s

Caveats

At the moment, the way the default filler checks whether it should fill a struct field or not is by comparing the current field value with the corresponding zero value of that type. This has a subtle implication: the zero value set explicitly by you will get overriden by default value during SetDefaults() call. So if you need to set the field to container zero value, you need to set it explicitly AFTER setting the defaults.

Take the basic example in the above section and change it slightly:

example := ExampleBasic{
    Bar: 0,
}
defaults.SetDefaults(example)
fmt.Println(example.Bar) //Prints: 33 instead of 0 (which is zero value for int)

example.Bar = 0 // set needed zero value AFTER applying defaults
fmt.Println(example.Bar) //Prints: 0

Pointer Set

Pointer field struct is a tricky usage to avoid covering existed values.

Take the basic example in the above section and change it slightly:

type ExamplePointer struct {
    Foo *bool   `default:"true"` //<-- StructTag with a default key
    Bar *string `default:"example"`
    Qux *int    `default:"22"`
    Oed *int64  `default:"64"`
}

...

boolZero := false
stringZero := ""
intZero := 0
example := &ExamplePointer{
    Foo: &boolZero,
    Bar: &stringZero,
    Qux: &intZero,
}
defaults.SetDefaults(example)

fmt.Println(*example.Foo) //Prints: false (zero value `false` for bool but not for bool ptr)
fmt.Println(*example.Bar) //Prints: "" (print "" which set in advance, not "example" for default)
fmt.Println(*example.Qux) //Prints: 0 (0 instead of 22)
fmt.Println(*example.Oed) //Prints: 64 (64, because the ptr addr is nil when SetDefaults)

It's also a very useful feature for web application which default values are needed while binding request json.

For example:

type ExamplePostBody struct {
    Foo *bool   `json:"foo" default:"true"` //<-- StructTag with a default key
    Bar *string `json:"bar" default:"example"`
    Qux *int    `json:"qux" default:"22"`
    Oed *int64  `json:"oed" default:"64"`
}

HTTP request seems like this:

curl --location --request POST ... \
... \
--header 'Content-Type: application/json' \
--data-raw '{
    "foo": false,
    "bar": "",
    "qux": 0
}'

Request handler:

func PostExampleHandler(c *gin.Context) {
    var reqBody ExamplePostBody
    if err := c.ShouldBindJSON(&reqBody); err != nil {
        c.JSON(http.StatusBadRequest, nil)
        return
    }
    defaults.SetDefaults(&reqBody)

    fmt.Println(*reqBody.Foo) //Prints: false (zero value `false` for bool but not for bool ptr)
    fmt.Println(*reqBody.Bar) //Prints: "" (print "" which set in advance, not "example" for default)
    fmt.Println(*reqBody.Qux) //Prints: 0 (0 instead of 22, did not confused from whether zero value is in json or not)
    fmt.Println(*reqBody.Oed) //Prints: 64 (In this case "oed" is not in req json, so set default 64)

    ...
}

License

MIT, see LICENSE

go-defaults's People

Contributors

mcuadros avatar zhlingbo avatar bc-vincent-zhao avatar rs avatar pagongamedev avatar russmatney avatar serabe avatar sergeybataev avatar

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.