Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support converting unmarshalled configs to interface{} #460

Merged
merged 8 commits into from
Sep 3, 2024

Conversation

BoskyWSMFN
Copy link
Contributor

@BoskyWSMFN BoskyWSMFN commented Aug 30, 2024

Fixed problem described in #459.
Nothing is broken so far.

Copy link

codecov bot commented Aug 30, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 82.9%. Comparing base (0d1fce1) to head (aafa9bd).
Report is 12 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@          Coverage Diff          @@
##            main    #460   +/-   ##
=====================================
  Coverage   82.8%   82.9%           
=====================================
  Files         62      62           
  Lines       2651    2664   +13     
=====================================
+ Hits        2197    2210   +13     
  Misses       371     371           
  Partials      83      83           
Files with missing lines Coverage Δ
internal/convert/converter.go 99.4% <100.0%> (+<0.1%) ⬆️

@BoskyWSMFN BoskyWSMFN changed the title Aded support converting unmarshalled configs to interface{} Added support converting unmarshalled configs to interface{} Aug 30, 2024
@@ -91,6 +91,10 @@ func (c Converter) convert(name string, from any, toVal reflect.Value) error { /
return c.convertString(name, fromVal, toVal)
case toVal.Kind() == reflect.Struct:
return c.convertStruct(name, fromVal, toVal)
case toVal.Kind() == reflect.Interface: // Right after all other checks.
toVal.Set(fromVal)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It needs a special handling if fromVal is map since the keys in map may be wrapped for case sensitive.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't get your point. Special handling is required for maps, asaik, but it is the caller's responsibility to deal with keys and values if the destination contains fields of type interface{}.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for confusion. To support case sensitive map key, the key in internal value has been wrapped with a special struct (https://github.com/nil-go/konf/blob/main/config.go#L166). So when unmarshaling back to map, it needs to unwrap the key back to string (case sensitive or not depends on configuration).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, there's no confusion. I just had doubts about whether special handling was really necessary here. I found a test case that clearly shows it is. =)

},
{
description: "map to interface",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added few more tests to check if maps.Unpack call is required. Seems to be excessive.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may miss test for Unpack in convert package. Here is the code calls maps.Unpack

key, value := maps.Unpack(fromValueVal.Interface())

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I may miss test for Unpack in convert package. Here is the code calls maps.Unpack

key, value := maps.Unpack(fromValueVal.Interface())

Seems to be tested indirectly.

@@ -554,6 +552,55 @@ func (c Converter) convertStruct(name string, fromVal, toVal reflect.Value) erro
}
}

func (c Converter) convertInterface(name string, fromVal, toVal reflect.Value) error {
switch fromVal.Kind() {
case reflect.Map:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible just creating a Map[string]any and then return the result from convert with new created map?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh... Right, it is. Haste makes waste.

}),
},
{
description: "packed KV and field to interface{}",
Copy link
Contributor Author

@BoskyWSMFN BoskyWSMFN Sep 2, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test case shows that special handling is necessary. Now, all complex data types will be treated as map[string]interface{}.

Copy link
Collaborator

@ktong ktong left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for the fixing.

@ktong
Copy link
Collaborator

ktong commented Sep 3, 2024

@BoskyWSMFN may I merge it now?

@BoskyWSMFN
Copy link
Contributor Author

@BoskyWSMFN may I merge it now?

Sure.

@ktong ktong merged commit a5488c9 into nil-go:main Sep 3, 2024
64 of 67 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants