From 7d0fb6b5305fd83b55cae59c57d82f55c973cc42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ram=C3=B3n=20=C3=81lvarez?= <86166683+ralvarezdev@users.noreply.github.com> Date: Wed, 18 Dec 2024 15:22:32 -0400 Subject: [PATCH] feat: Added validator service --- field/{ => birthdate}/errors.go | 2 +- go.mod | 12 ++- go.sum | 21 +++- service/errors.go | 10 ++ service/validator.go | 101 ++++++++++++++++++ .../validations/struct_fields_validations.go | 4 +- 6 files changed, 144 insertions(+), 6 deletions(-) rename field/{ => birthdate}/errors.go (83%) create mode 100644 service/errors.go create mode 100644 service/validator.go diff --git a/field/errors.go b/field/birthdate/errors.go similarity index 83% rename from field/errors.go rename to field/birthdate/errors.go index 7f98ca4..e76e847 100644 --- a/field/errors.go +++ b/field/birthdate/errors.go @@ -1,4 +1,4 @@ -package field +package birthdate import ( "errors" diff --git a/go.mod b/go.mod index c036c72..b02e924 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,14 @@ module github.com/ralvarezdev/go-validator go 1.23.4 -require github.com/ralvarezdev/go-flags v0.2.0 // indirect +require ( + github.com/ralvarezdev/go-flags v0.2.0 + google.golang.org/grpc v1.69.2 + google.golang.org/protobuf v1.36.0 +) + +require ( + github.com/ralvarezdev/go-logger v0.1.0 // indirect + golang.org/x/sys v0.26.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect +) diff --git a/go.sum b/go.sum index 69b1e58..3d06479 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,20 @@ -github.com/ralvarezdev/go-flags v0.1.0 h1:WG6eMbS2yL+UYtI3X8R/HbisrfEgzLiMKMWqXanwyys= -github.com/ralvarezdev/go-flags v0.1.0/go.mod h1:pYw9H7NJ07Y5asZDC/EI5bpBLR0kdL2ISsh6X5ws+3s= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/ralvarezdev/go-flags v0.2.0 h1:NdMuJgCv2f9RysYOMHQQM1BT9HGv6PPNDRYPT5T+d2c= github.com/ralvarezdev/go-flags v0.2.0/go.mod h1:pYw9H7NJ07Y5asZDC/EI5bpBLR0kdL2ISsh6X5ws+3s= +github.com/ralvarezdev/go-logger v0.1.0 h1:i2AI1nlxU6Hizvk75Vc8wtFydiVrqIeeRbJwiuO/69A= +github.com/ralvarezdev/go-logger v0.1.0/go.mod h1:v5OvFrkS+wsYNTCVegXWiRhBtcYrQJr4LDMDntvpAos= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= +google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU= +google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= +google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ= +google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= diff --git a/service/errors.go b/service/errors.go new file mode 100644 index 0000000..99dc3db --- /dev/null +++ b/service/errors.go @@ -0,0 +1,10 @@ +package service + +import ( + "errors" +) + +var ( + NilValidatorError = errors.New("validator cannot be nil") + NilMessageError = errors.New("message cannot be nil") +) diff --git a/service/validator.go b/service/validator.go new file mode 100644 index 0000000..5a6a4e3 --- /dev/null +++ b/service/validator.go @@ -0,0 +1,101 @@ +package service + +import ( + goflagmode "github.com/ralvarezdev/go-flags/mode" + govalidatorbirthdate "github.com/ralvarezdev/go-validator/field/birthdate" + govalidatormail "github.com/ralvarezdev/go-validator/field/mail" + govalidatormapper "github.com/ralvarezdev/go-validator/structs/mapper" + govalidatorvalidations "github.com/ralvarezdev/go-validator/structs/validations" + "google.golang.org/protobuf/types/known/timestamppb" + "time" +) + +type ( + // Validator interface + Validator interface { + ModeFlag() *goflagmode.Flag + ValidateEmail( + emailField string, + email string, + mapperValidations *govalidatorvalidations.MapperValidations, + ) + ValidateBirthdate( + birthdateField string, + birthdate *timestamppb.Timestamp, + mapperValidations *govalidatorvalidations.MapperValidations, + ) + ValidateNilFields(request interface{}, mapper *govalidatormapper.Mapper) ( + *govalidatorvalidations.MapperValidations, + error, + ) + CheckValidations(mapperValidations *govalidatorvalidations.MapperValidations) *string + } + + // DefaultValidator struct + DefaultValidator struct { + mode *goflagmode.Flag + } +) + +// NewDefaultValidator creates a new default validator +func NewDefaultValidator(mode *goflagmode.Flag) *DefaultValidator { + return &DefaultValidator{ + mode: mode, + } +} + +// ModeFlag returns the mode flag +func (d *DefaultValidator) ModeFlag() *goflagmode.Flag { + return d.mode +} + +// ValidateEmail validates the email address field +func (d *DefaultValidator) ValidateEmail( + emailField string, + email string, + mapperValidations *govalidatorvalidations.MapperValidations, +) { + if _, err := govalidatormail.ValidMailAddress(email); err != nil { + mapperValidations.AddFailedFieldValidationError( + emailField, + govalidatormail.InvalidMailAddressError, + ) + } +} + +// ValidateBirthdate validates the birthdate field +func (d *DefaultValidator) ValidateBirthdate( + birthdateField string, + birthdate *timestamppb.Timestamp, + mapperValidations *govalidatorvalidations.MapperValidations, +) { + if birthdate == nil || birthdate.AsTime().After(time.Now()) { + mapperValidations.AddFailedFieldValidationError( + birthdateField, + govalidatorbirthdate.InvalidBirthdateError, + ) + } +} + +// ValidateNilFields validates the nil fields +func (d *DefaultValidator) ValidateNilFields( + request interface{}, + mapper *govalidatormapper.Mapper, +) (*govalidatorvalidations.MapperValidations, error) { + return govalidatorvalidations.ValidateMapperNilFields( + request, + mapper, + d.mode, + ) +} + +// CheckValidations checks the validations and returns a pointer to the error message +func (d *DefaultValidator) CheckValidations( + mapperValidations *govalidatorvalidations.MapperValidations, +) *string { + // Get the error message from the validations if there are any + if mapperValidations.HasFailed() { + return mapperValidations.StringPtr() + } + return nil +} diff --git a/structs/validations/struct_fields_validations.go b/structs/validations/struct_fields_validations.go index 076c448..eb1f899 100644 --- a/structs/validations/struct_fields_validations.go +++ b/structs/validations/struct_fields_validations.go @@ -215,8 +215,8 @@ func (s *MapperValidations) FailedValidationsMessage(level int) *string { return &messageString } -// String returns a formatted error message. If there are no failed validations, it returns nil -func (s *MapperValidations) String() *string { +// StringPtr returns a pointer to the failed validations message +func (s *MapperValidations) StringPtr() *string { // Return the failed validations message message := s.FailedValidationsMessage(0)