pdefault

package module
v0.1.0-beta.2 Latest Latest
Warning

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

Go to latest
Published: May 25, 2025 License: MIT Imports: 4 Imported by: 1

README

pdefault

Go Report Card Go CI codecov

pdefault provides functionality to parse and set default values for struct fields based on their "default" tags

Table of Contents
  1. About The Project
  2. Features
  3. Getting Started
  4. Usage
  5. Supported/Unsupported Field Type
  6. License
  7. Contact

About The Project

The pdefault package simplifies the process of setting default values for struct fields in Go when they are unset (i.e., at their zero value or nil for pointers). Instead of manually checking each field for its zero value and assigning defaults, pdefault uses struct tags to automatically parse and set default values, making your code cleaner and more maintainable. This project was inspired by the need for a streamlined, reusable solution to initialize struct fields with predefined defaults, especially in scenarios involving configuration structs, data models, or nested structures.

Key Features

  • Automatic Default Value Setting: The Defaults function processes a non-nil pointer to a struct, setting default values for exported fields based on their "default" tags (configurable via the package-level Tag variable).

  • Recursive Struct Handling: Nested structs are processed recursively, applying default values to their fields.

  • Broad Type Support: Supports a wide range of field types, including numeric types, strings, booleans, maps, slices, arrays, and their pointers. See Supported/Unsupported Field Types

  • Robust Error Handling: Returns errors for invalid inputs, unexported fields, empty tags (for non-struct fields), parsing failures, out-of-range values, or unsupported types.

Getting Started

Note that we only supports the two most recent minor versions of Go.

go get github.com/lthphuw/pdefault@latest

Usage

With pdefault, you can define defaults in struct tags and let the Defaults function handle initialization:

type Config struct {
    Port int    `default:"8080"`
    Host string `default:"localhost"`
}

func main() {
    var config Config
    // Load from env
    // ...

    // Set defaults
    if err := pdefault.Defaults(&config); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Port: %d, Host: %s\n", config.Port, config.Host)
    // Output: Port: 8080, Host: localhost
}

This approach reduces boilerplate code, improves readability, and ensures consistent default value handling across your application.

Here’s a another complete example demonstrating various field types:

package main

import (
    "fmt"
    "pdefault"
)

type Nested struct {
    Value int `default:"100"`
}

type Example struct {
    ID      int            `default:"123"`
    Name    *string        `default:"hello"`
    Data    map[string]any `default:"{\"key\":\"value\",\"num\":42}"`
    Numbers [3]int         `default:"[1,2,3]"`
    Nested  Nested         `default:"{}"`
}

func main() {
    var s Example
    if err := pdefault.Defaults(&s); err != nil {
        fmt.Printf("Error: %v\n", err)
        return
    }
    fmt.Printf("ID: %d, Name: %v, Data: %v, Numbers: %v, Nested.Value: %d\n",
        s.ID, *s.Name, s.Data, s.Numbers, s.Nested.Value)
}

Output:

ID: 123, Name: hello, Data: map[key:value num:42], Numbers: [1 2 3], Nested.Value: 100

Supported/Unsupported Field Type

Supported Field Types and Example Tags

The Defaults function supports the following field types with their respective "default" tag formats:

  • Numeric Types:

    • int: default:"123"

    • int8: default:"127"

    • int16: default:"32767"

    • int32: default:"2147483647"

    • int64: default:"9223372036854775807"

    • uint: default:"123"

    • uint8: default:"255"

    • uint16: default:"65535"

    • uint32: default:"4294967295"

    • uint64: default:"18446744073709551615"

    • float32: default:"3.14"

    • float64: default:"3.14159265359"

    • complex64: default:"1+2i"

    • complex128: default:"1.5+2.5i"

  • string: default:"hello"

  • bool: default:"true"

  • map (e.g., map[string]any): default:"{"key":"value","num":42}"

  • slice (e.g., []string): default:"["a","b","c"]"

  • array (e.g., [3]int): default:"[1,2,3]"

struct: triggers recursive default setting for nested fields.

Pointers to Above Types:

  • \*int: default:"123"

  • \*string: default:"hello"

  • \*map[string]any: default:"{"key":"value"}"

  • \*[]string: default:"["a","b"]"

  • \*[3]int: default:"[1,2,3]"

  • \*struct: triggers recursive default setting for nested fields.

  • ...

Unsupported Field Types

The following types are not supported by Defaults:

  • Function types (e.g., func(), *func())

  • Channels (e.g., chan int)

  • Interfaces (e.g., interface{})

  • Unsafe pointers (e.g., unsafe.Pointer)

  • Any other types not listed above

License

This project is licensed under the MIT License – see the LICENSE file for details.

Contact

Maintained by Phu.
For questions, feedback, or support, please contact: lthphuw@gmail.com

(back to top)

Documentation

Overview

Package pdefault provides functionality to parse and set default values for struct fields based on their "default" tags. The Defaults function processes a non-nil pointer to a struct, setting default values for exported fields that are unset (zero values for non-pointers or nil for pointers) using the tag key specified by the package-level variable Tag (defaulting to "default"). Nested structs are processed recursively. Fields without a "default" tag are skipped unless they are structs or struct pointers.

Supported field types and example default tags:

  • int: `default:"123"`
  • int8: `default:"127"`
  • int16: `default:"32767"`
  • int32: `default:"2147483647"`
  • int64: `default:"9223372036854775807"`
  • uint: `default:"123"`
  • uint8: `default:"255"`
  • uint16: `default:"65535"`
  • uint32: `default:"4294967295"`
  • uint64: `default:"18446744073709551615"`
  • float32: `default:"3.14"`
  • float64: `default:"3.14159265359"`
  • complex64: `default:"1+2i"`
  • complex128: `default:"1.5+2.5i"`
  • string: `default:"hello"`
  • bool: `default:"true"`
  • map (e.g., map[string]any): `default:"{\"key\":\"value\",\"num\":42}"`
  • slice (e.g., []string): `default:"[\"a\",\"b\",\"c\"]"`
  • array (e.g., [3]int): `default:"[1,2,3]"`
  • struct (triggers recursive default setting for nested struct fields)
  • Pointers to the above types (e.g., *int, *string, *map[string]any, *[]string, *[3]int, *struct):
  • *int: `default:"123"`
  • *string: `default:"hello"`
  • *map[string]any: `default:"{\"key\":\"value\"}"`
  • *[]string: `default:"[\"a\",\"b\"]"`
  • *[3]int: `default:"[1,2,3]"`
  • *struct (recursively processes nested struct fields)

Unsupported field types:

  • Function types (e.g., func(), *func())
  • Channels (e.g., chan int)
  • Interfaces (e.g., interface{})
  • Unsafe pointers (e.g., unsafe.Pointer)
  • Any other types not listed above

Default tag values must be valid for the field's type. Numeric types require valid numeric strings, bool requires "true" or "false", strings can be plain or JSON-escaped, and maps/slices/arrays require JSON-formatted strings. Errors are returned for invalid inputs, unexported fields, empty tags (for non-struct fields), parsing failures (e.g., invalid number formats, JSON syntax errors), out-of-range values, or unsupported types. The Defaults function recursively processes nested structs to apply their default tags.

Index

Constants

This section is empty.

Variables

View Source
var Tag = defaultTag

Tag specifies the struct tag key used to parse default values for fields.

Functions

func Defaults

func Defaults(s any) error

Defaults sets default values for struct fields based on their "default" tags.

It takes a pointer to a struct as input and processes each exported field with a "default" tag. If a field is unset (zero value for non-pointers or nil for pointers), the function parses the tag value and sets it according to the field's type. Supported types include int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, float32, float64, complex64, complex128, bool, string, map, slice, array, and nested structs (including pointers to these types). The function recursively processes nested structs. It skips unexported fields, non-zero fields, and fields without a "default" tag unless they are structs or struct pointers. Errors are returned for invalid inputs, unsupported types, or parsing failures.

The tag key used for parsing is defined by the package-level variable Tag, which defaults to "default".

func ParseArray

func ParseArray(str string, targetType reflect.Type) (any, error)

ParseArray parses a string to a slice of any values representing an array. It expects a JSON-like string (e.g., [1,2,3]).

func ParseBool

func ParseBool(str string) (bool, error)

ParseBool parses a string to a boolean.

func ParseComplex64

func ParseComplex64(str string) (complex64, error)

ParseComplex64 parses a string to an complex64.

func ParseComplex128

func ParseComplex128(str string) (complex128, error)

ParseComplex128 parses a string to an complex128.

func ParseFloat32

func ParseFloat32(str string) (float32, error)

ParseFloat32 parses a string to an float32.

func ParseFloat64

func ParseFloat64(str string) (float64, error)

ParseFloat64 parses a string to an float64.

func ParseInt

func ParseInt(str string) (int, error)

ParseInt parses a string to an integer.

func ParseInt8

func ParseInt8(str string) (int8, error)

ParseInt8 parses a string to an int8.

func ParseInt16

func ParseInt16(str string) (int16, error)

ParseInt16 parses a string to an int16.

func ParseInt32

func ParseInt32(str string) (int32, error)

ParseInt32 parses a string to an int32.

func ParseInt64

func ParseInt64(str string) (int64, error)

ParseInt64 parses a string to an int64.

func ParseMap

func ParseMap(str string, targetType reflect.Type) (any, error)

ParseMap parses a string to a map with any keys and values. It expects a JSON-like string (e.g., "{<key>:<value>}"). String value should be \"<value>\".

func ParseSlice

func ParseSlice(str string, targetType reflect.Type) (any, error)

ParseSlice parses a string to a slice of any values. It expects a JSON-like string (e.g., [1,2,3]).

func ParseString

func ParseString(str string) (string, error)

ParseString parse a string to string

func ParseUint

func ParseUint(str string) (uint, error)

ParseUint parses a string to an uint.

func ParseUint8

func ParseUint8(str string) (uint8, error)

ParseUint8 parses a string to an uint8.

func ParseUint16

func ParseUint16(str string) (uint16, error)

ParseUint16 parses a string to an uint16.

func ParseUint32

func ParseUint32(str string) (uint32, error)

ParseUint32 parses a string to an uint32.

func ParseUint64

func ParseUint64(str string) (uint64, error)

ParseUint64 parses a string to an uint64.

func SetDefaultTag

func SetDefaultTag(tag string)

SetDefaultTag sets the tag name of default tag

func Zero

func Zero[T any]() T

Zero returns the zero value for type T.

Types

This section is empty.

Jump to

Keyboard shortcuts

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