Skip to content

Commit

Permalink
Switch from mitchellh/mapstructure to go-viper/mapstructure (#69)
Browse files Browse the repository at this point in the history
Reference:
mitchellh/mapstructure#349 (comment)

mitchellh stops the maintenance for
[mapstructure](https://github.com/mitchellh/mapstructure) and other
mitchellh/mapstructure#349 (comment).

The mapstructure project is already forked by viper project, since they
have a strong dependency against it.

https://github.com/go-viper/mapstructure
  • Loading branch information
ktong authored Jan 7, 2024
1 parent 6953fb7 commit ef74c14
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 76 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Changed

- Switch from mitchellh/mapstructure to go-viper/mapstructure (#69).

## [v0.3.0] - 11/17/2023

### Changed
Expand Down
74 changes: 2 additions & 72 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,13 @@ package konf

import (
"context"
"encoding"
"errors"
"fmt"
"log/slog"
"reflect"
"strings"
"sync"

"github.com/mitchellh/mapstructure"
"github.com/go-viper/mapstructure/v2"

"github.com/ktong/konf/internal/maps"
)
Expand Down Expand Up @@ -47,7 +45,7 @@ func New(opts ...Option) *Config {
decodeHook: mapstructure.ComposeDecodeHookFunc(
mapstructure.StringToTimeDurationHookFunc(),
mapstructure.StringToSliceHookFunc(","),
textUnmarshalerHookFunc(),
mapstructure.TextUnmarshallerHookFunc(),
),
values: make(map[string]any),
onChanges: make(map[string][]func(*Config)),
Expand Down Expand Up @@ -257,71 +255,3 @@ func (c *Config) Unmarshal(path string, target any) error {

return nil
}

// textUnmarshalerHookFunc is a fixed version of mapstructure.TextUnmarshallerHookFunc.
// This hook allows to additionally unmarshal text into custom string types
// that implement the encoding.Text(Un)Marshaler interface(s).
//
//nolint:wrapcheck
func textUnmarshalerHookFunc() mapstructure.DecodeHookFuncType {
return func(
from reflect.Type,
to reflect.Type, //nolint:varnamelen
data interface{},
) (interface{}, error) {
if from.Kind() != reflect.String {
return data, nil
}
result := reflect.New(to).Interface()
unmarshaller, ok := result.(encoding.TextUnmarshaler)
if !ok {
return data, nil
}

// default text representation is the actual value of the `from` string
var (
dataVal = reflect.ValueOf(data)
text = []byte(dataVal.String())
)
if from.Kind() == to.Kind() { //nolint:nestif
// source and target are of underlying type string
var (
err error
ptrVal = reflect.New(dataVal.Type())
)
if !ptrVal.Elem().CanSet() {
// cannot set, skip, this should not happen
if err := unmarshaller.UnmarshalText(text); err != nil {
return nil, err
}

return result, nil
}
ptrVal.Elem().Set(dataVal)

// We need to assert that both, the value type and the pointer type
// do (not) implement the TextMarshaller interface before proceeding and simply
// using the string value of the string type.
// it might be the case that the internal string representation differs from
// the (un)marshaled string.
for _, v := range []reflect.Value{dataVal, ptrVal} {
if marshaller, ok := v.Interface().(encoding.TextMarshaler); ok {
text, err = marshaller.MarshalText()
if err != nil {
return nil, err
}

break
}
}
}

// text is either the source string's value or the source string type's marshaled value
// which may differ from its internal string value.
if err := unmarshaller.UnmarshalText(text); err != nil {
return nil, err
}

return result, nil
}
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ module github.com/ktong/konf

go 1.21

require github.com/mitchellh/mapstructure v1.5.0
require github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1 h1:TQcrn6Wq+sKGkpyPvppOz99zsMBaUOKXq6HSv655U1c=
github.com/go-viper/mapstructure/v2 v2.0.0-alpha.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
2 changes: 1 addition & 1 deletion option.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

package konf

import "github.com/mitchellh/mapstructure"
import "github.com/go-viper/mapstructure/v2"

// WithDelimiter provides the delimiter used when specifying config paths.
// The delimiter is used to separate keys in the path.
Expand Down

0 comments on commit ef74c14

Please sign in to comment.