Skip to content

Is there a tag like len_if #1420

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

Open
picone opened this issue Apr 23, 2025 · 3 comments
Open

Is there a tag like len_if #1420

picone opened this issue Apr 23, 2025 · 3 comments

Comments

@picone
Copy link

picone commented Apr 23, 2025

My case:

We should ensure the Values must has value if Enabled is true.

struct Foo {
  Enabled bool
  Values []string `validate:"required_if=Enabled true,dive,oneof=a b c"`
}

If the Values is nil, the validator work well, but if the Values is an empty slice, it can pass the validator.

I've read the docs, I think it work as expected:

For slices, maps, pointers, interfaces, channels and functions ensures the value is not nil. For structs ensures value is not the zero value.

So, I think we should add a tag like len_if?

struct Foo {
  Enabled bool
  Values []string `validate:"len_if=Enabled true 0,dive,oneof=a b c"`
}
@zemzale
Copy link
Member

zemzale commented Apr 30, 2025

It actually does seem that this doesn't work on cases where the slice is not nil, but has no values inside it.

My test case looks like:

type Foo struct {
	Enabled bool
	Values  []string `validate:"required_if=Enabled true,omitempty,min=1,dive,oneof=a b c"`
}

func TestFoo(t *testing.T) {
	val := validator.New()

	err := val.Struct(Foo{
		Enabled: true,
		Values:  []string{},
	})

	assert.Error(t, err)

	err = val.Struct(Foo{
		Enabled: true,
	})

	assert.Error(t, err)

	err = val.Struct(Foo{
		Enabled: false,
	})
	assert.NoError(t, err)

	err = val.Struct(Foo{
		Enabled: false,
		Values:  []string{},
	})

	assert.NoError(t, err) // This one fails, since omitempty doesn't trigger on slices that have no values inside them.
}

I don't like the len_if aproach:

  • we going to end up needing len_if min_if max_if and so on, which is not great
  • the 3 parameters inside the struct tag is pretty insane

Usually the omitempty works, but it doesn't work with slices that are initialized, but don't have any values.

There are like two approaches we could take:

  • add skip_if (naming could be changed) so that we can skip the validation unless some conditions are met, in this case it would be something like skip_if=Enabled false
  • add new validation that would be like omitempty that would fail on slices if they are nil or len(s) == 0

@deankarn
Copy link
Contributor

@zemzale cant remember off the top of my head but don’t we have a new omitzero tag that could be used in place of omitempty here?

@picone
Copy link
Author

picone commented May 4, 2025

@zemzale cant remember off the top of my head but don’t we have a new omitzero tag that could be used in place of omitempty here?

Yeah, I find it here: #1289

I think this can resolve my issue.

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

No branches or pull requests

3 participants