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

[BUG] User specified value 0 is ignored when default is not zero #222

Closed
1 task done
klajok opened this issue Sep 26, 2024 · 2 comments
Closed
1 task done

[BUG] User specified value 0 is ignored when default is not zero #222

klajok opened this issue Sep 26, 2024 · 2 comments
Labels

Comments

@klajok
Copy link

klajok commented Sep 26, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

Following code prints the default integer value 10 of field Level, despite the fact that specified level was "0".

type Example struct {
	Level int `schema:"level,default:10"`
}

func main() {
	var example Example
	input := map[string][]string{"level": {"0"}}

	schema.NewDecoder().Decode(&example, input)

	// instead of 0 program prints 10
	fmt.Println(example.Level)
}

Expected Behavior

Decoder should not ignore user specified integer value even if it is equal to 0. Program should print 0.

Steps To Reproduce

Run the above program.

Anything else?

This bug affects fields of type int, uint32, float64,... and so on.

@klajok klajok added the bug label Sep 26, 2024
@jaitaiwan
Copy link
Member

Mismatched types. Should be map[string]string{} not map[string][]string{}

@klajok
Copy link
Author

klajok commented Sep 27, 2024

I think the type shown in the example snippet is correct. It matches the type url.Values. Additionally the proposed type map[string]string causes compilation error.

But... today I have finally spotted big blue note at the very bottom of README:

Because primitive types like int, float, bool, unint and their variants have their default (or zero) values set by Golang, it is not possible to distinguish them from a provided value when decoding/encoding form values. In this case, the value provided by the default option tag will be always applied. (...) In such cases, it is highly recommended to use pointers to allow schema to distinguish between when a form field has no provided value and when a form has a value equal to the corresponding default set by Golang for a particular type.

I'm not sure about encoding, but in case decoding we have all values in the form of map of string list. We can easily distinguish between [""], ["0"] and no entry in the values map.

As a workaround we use following code (adapted to the reported "example") - it works but looks ugly:

value := input["level"] 
// inspect **last** value of the potentially polluted HTTP param (to be consistent
// with behavior of other library which parses HTTP parameters)
if len(value) > 0 && value[len(value)-1] == "0" {
  example.Level = 0
}

This proves that it is possible to "distinguish them [default (or zero) values] from a provided value".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants