go-playground / validator

:100:Go Struct and Field validation, including Cross Field, Cross Struct, Map, Slice and Array diving
MIT License
16.64k stars 1.32k forks source link

Add support for validating against uuid values that are structs which implement the Stringer interface. #1189

Closed JoshGlazebrook closed 11 months ago

JoshGlazebrook commented 11 months ago

Fixes Or Enhances

This adds the ability to validate UUIDs that have an underlying struct value but also implement the Stringer interface. This should cover most UUID implementations (google's uuid, etc).

Implements: #900, specifically https://github.com/go-playground/validator/issues/900#issuecomment-1046030775.

Make sure that you've checked the boxes below before you submit PR:

@go-playground/validator-maintainers

coveralls commented 11 months ago

Coverage Status

coverage: 73.857% (+0.008%) from 73.849% when pulling fc0946708ca8e18acb87b4ad78d2ac8518395e40 on JoshGlazebrook:uuid-stringer into 94a637ab9fbbb0bc0fe8a278f0352d0b14e2c365 on go-playground:master.

deankarn commented 11 months ago

@JoshGlazebrook this PR is close :)

But I think it will fail for alias types that an implement fmt.Stringer. The type needs to be checked to see if the kind is already a string before attempting the cast. eg.

type uuidAlias string

func (u uuidAlias) String() string {
    return "This is a UUID " + string(u)
}

I think the new helper can be changed like so to avoid this and maintain 100% backward compatibility:

func fieldMatchesRegexByStringerValOrString(regex *regexp.Regexp, fl FieldLevel) bool {
    switch fl.Field().Kind() {
    case reflect.String:
        return regex.MatchString(fl.Field().String())
    default:
        if stringer, ok := fl.Field().Interface().(fmt.Stringer); ok {
            return regex.MatchString(stringer.String())
        } else {
            return regex.MatchString(fl.Field().String())
        }
    }
}
deankarn commented 11 months ago

I will merge and then make these changes.

JoshGlazebrook commented 11 months ago

Thank you!