MCPcopy Create free account
hub / github.com/creasty/defaults

github.com/creasty/defaults

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.9.0 ↗ · + Follow · compare 3 versions
218 symbols 545 edges 19 files ⚖ MIT 78 documented · 36% updated 4mo agov1.8.0 · 2024-08-13★ 86212 open issues

Browse by type

Functions 146 Types & classes 72
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

!!! Looking for a new maintainer !!!

defaults

CI codecov GitHub release License

Initialize structs with default values

  • Supports almost all kind of types
  • Scalar types
    • int/8/16/32/64, uint/8/16/32/64, float32/64
    • uintptr, bool, string
  • Complex types
    • map, slice, struct
  • Nested types
    • map[K1]map[K2]Struct, []map[K1]Struct[]
  • Aliased types
    • time.Duration
    • e.g., type Enum string
  • Pointer types
    • e.g., *SampleStruct, *int
  • Recursively initializes fields in a struct
  • Dynamically sets default values by:
  • Implementing the defaults.Setter interface, or
  • Implementing encoding.TextUnmarshaler, which takes precedence over defaults.Setter -- the tag is handed to UnmarshalText and SetDefaults is not called
  • Preserves non-initial values from being reset with a default value
  • A field is written only while it still holds its type's zero value. No scalar type can tell an unspecified value from its zero value — an int left alone is 0, a string is "", a bool is false — so a zero the caller set on purpose is indistinguishable from one never set, and the default replaces it.
  • Use a pointer where that distinction matters. nil means unspecified, and a pointer to the zero value is preserved: *bool is the way to let false survive a default:"true".

Usage

package main

import (
    "encoding/json"
    "fmt"
    "math/rand"

    "github.com/creasty/defaults"
)

type Gender string

type Sample struct {
    Name    string `default:"John Smith"`
    Age     int    `default:"27"`
    Gender  Gender `default:"m"`
    Working bool   `default:"true"`

    SliceInt    []int    `default:"[1, 2, 3]"`
    SlicePtr    []*int   `default:"[1, 2, 3]"`
    SliceString []string `default:"[\"a\", \"b\"]"`

    MapNull            map[string]int          `default:"{}"`
    Map                map[string]int          `default:"{\"key1\": 123}"`
    MapOfStruct        map[string]OtherStruct  `default:"{\"Key2\": {\"Foo\":123}}"`
    MapOfPtrStruct     map[string]*OtherStruct `default:"{\"Key3\": {\"Foo\":123}}"`
    MapOfStructWithTag map[string]OtherStruct  `default:"{\"Key4\": {\"Foo\":123}}"`

    Struct    OtherStruct  `default:"{\"Foo\": 123}"`
    StructPtr *OtherStruct `default:"{\"Foo\": 123}"`

    NoTag    OtherStruct // Recurses into a nested struct by default
    NoOption OtherStruct `default:"-"` // no option
}

type OtherStruct struct {
    Hello  string `default:"world"` // Tags in a nested struct also work
    Foo    int    `default:"-"`
    Random int    `default:"-"`
}

// SetDefaults implements defaults.Setter interface
func (s *OtherStruct) SetDefaults() {
    if defaults.CanUpdate(s.Random) { // Check if it's a zero value (recommended)
        s.Random = rand.Int() // Set a dynamic value
    }
}

func main() {
    obj := &Sample{}
    if err := defaults.Set(obj); err != nil {
        panic(err)
    }

    out, err := json.MarshalIndent(obj, "", "   ")
    if err != nil {
        panic(err)
    }
    fmt.Println(string(out))

    // Output:
    // {
    //  "Name": "John Smith",
    //  "Age": 27,
    //  "Gender": "m",
    //  "Working": true,
    //  "SliceInt": [
    //      1,
    //      2,
    //      3
    //  ],
    //  "SlicePtr": [
    //      1,
    //      2,
    //      3
    //  ],
    //  "SliceString": [
    //      "a",
    //      "b"
    //  ],
    //  "MapNull": {},
    //  "Map": {
    //      "key1": 123
    //  },
    //  "MapOfStruct": {
    //      "Key2": {
    //          "Hello": "world",
    //          "Foo": 123,
    //          "Random": 5577006791947779410
    //      }
    //  },
    //  "MapOfPtrStruct": {
    //      "Key3": {
    //          "Hello": "world",
    //          "Foo": 123,
    //          "Random": 8674665223082153551
    //      }
    //  },
    //  "MapOfStructWithTag": {
    //      "Key4": {
    //          "Hello": "world",
    //          "Foo": 123,
    //          "Random": 6129484611666145821
    //      }
    //  },
    //  "Struct": {
    //      "Hello": "world",
    //      "Foo": 123,
    //      "Random": 4037200794235010051
    //  },
    //  "StructPtr": {
    //      "Hello": "world",
    //      "Foo": 123,
    //      "Random": 3916589616287113937
    //  },
    //  "NoTag": {
    //      "Hello": "world",
    //      "Foo": 0,
    //      "Random": 6334824724549167320
    //  },
    //  "NoOption": {
    //      "Hello": "",
    //      "Foo": 0,
    //      "Random": 0
    //  }
    // }
}

Extension points exported contracts — how you extend this code

browse all types & interfaces →

Core symbols most depended-on inside this repo

browse all functions →

Shape

Function 126
Struct 47
TypeAlias 24
Method 20
Interface 1

Languages

Go100%

Modules by API surface

set_scalar_test.go31 symbols
setter_test.go25 symbols
set_unmarshaler_test.go24 symbols
set_map_test.go15 symbols
set_struct_test.go14 symbols
set_slice_test.go14 symbols
set_pointer_test.go14 symbols
set_optout_test.go12 symbols
set_preserve_test.go10 symbols
set_error_test.go9 symbols
example_test.go9 symbols
set_nesting_test.go8 symbols

Dependencies from manifests, versioned

go.yaml.in/yaml/v3v3.0.5 · 1×

For agents

$ claude mcp add defaults \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page