From 1c255b7f15f5c089abcd15aeef86d364c9f041ca Mon Sep 17 00:00:00 2001 From: Adam Chalkley Date: Fri, 1 Jul 2022 08:21:28 -0500 Subject: [PATCH] Further validation refactoring - rename `validation` package back to original name of `validator` - attempting to follow the guideline of naming a package based on what it provides, not what it does - drop "Must" prefix from validation methods in an effort to make the method names sound more natural - add Validator.NoNilValuesInCollection method - add validation handling for ColumnItems type alias ([]*Element) - use Validator methods for validation of Column type Further refactoring could be beneficial, as would further conversion of Validate method implementations to use of the validator package. refs GH-157 --- adaptivecard/adaptivecard.go | 223 ++++++++++-------- internal/{validation => validator}/doc.go | 6 +- .../validation.go => validator/validator.go} | 130 ++++++---- 3 files changed, 222 insertions(+), 137 deletions(-) rename internal/{validation => validator}/doc.go (70%) rename internal/{validation/validation.go => validator/validator.go} (66%) diff --git a/adaptivecard/adaptivecard.go b/adaptivecard/adaptivecard.go index bf944f4..3eef2a1 100644 --- a/adaptivecard/adaptivecard.go +++ b/adaptivecard/adaptivecard.go @@ -19,7 +19,7 @@ import ( "strings" goteamsnotify "github.com/atc0005/go-teams-notify/v2" - "github.com/atc0005/go-teams-notify/v2/internal/validation" + "github.com/atc0005/go-teams-notify/v2/internal/validator" ) // General constants. @@ -541,6 +541,10 @@ type FactSet Element // Columns is a collection of Column values. type Columns []Column +// ColumnItems is a collection of card elements that should be rendered inside +// of the column. +type ColumnItems []*Element + // Column is a container used by a ColumnSet element type. Each container // may contain one or more elements. // @@ -890,9 +894,9 @@ func (m Message) Validate() error { return m.ValidateFunc() } - v := validation.Validator{} + v := validator.Validator{} - v.MustBeFieldHasSpecificValue( + v.FieldHasSpecificValue( m.Type, "type", TypeMessage, @@ -902,12 +906,12 @@ func (m Message) Validate() error { // We need an attachment (containing one or more Adaptive Cards) in order // to generate a valid Message for Microsoft Teams delivery. - v.MustBeNotEmptyCollection("Attachments", m.Type, ErrMissingValue, m.Attachments) + v.NotEmptyCollection("Attachments", m.Type, ErrMissingValue, m.Attachments) - v.MustSelfValidate(Attachments(m.Attachments)) + v.SelfValidate(Attachments(m.Attachments)) // Optional field, but only specific values permitted if set. - v.MustBeInListIfFieldValNotEmpty( + v.InListIfFieldValNotEmpty( m.AttachmentLayout, "AttachmentLayout", "message", @@ -920,9 +924,9 @@ func (m Message) Validate() error { // Validate asserts that fields have valid values. func (a Attachment) Validate() error { - v := validation.Validator{} + v := validator.Validator{} - v.MustBeFieldHasSpecificValue( + v.FieldHasSpecificValue( a.ContentType, "attachment type", AttachmentContentType, @@ -946,7 +950,7 @@ func (a Attachments) Validate() error { // Validate asserts that fields have valid values. func (c Card) Validate() error { - v := validation.Validator{} + v := validator.Validator{} // TODO: Version field validation // @@ -955,7 +959,7 @@ func (c Card) Validate() error { // to assert that relationship, we skip applying validation for that value // for now. - v.MustBeFieldHasSpecificValue( + v.FieldHasSpecificValue( c.Type, "type", TypeAdaptiveCard, @@ -965,7 +969,7 @@ func (c Card) Validate() error { // While the schema value should be set it is not strictly required. If it // is set, we assert that it is the correct value. - v.MustBeFieldHasSpecificValueIfFieldNotEmpty( + v.FieldHasSpecificValueIfFieldNotEmpty( c.Schema, "Schema", AdaptiveCardSchema, @@ -975,7 +979,7 @@ func (c Card) Validate() error { // Both are optional fields, unless MinHeight is set in which case // VerticalContentAlignment is required. - v.MustBeSuccessfulFuncCall( + v.SuccessfulFuncCall( func() error { return assertHeightAlignmentFieldsSetWhenRequired( c.MinHeight, c.VerticalContentAlignment, @@ -983,14 +987,14 @@ func (c Card) Validate() error { }, ) - v.MustBeSuccessfulFuncCall( + v.SuccessfulFuncCall( func() error { return assertCardBodyHasMention(c.Body, c.MSTeams.Entities) }, ) - v.MustSelfValidate(Elements(c.Body)) - v.MustSelfValidate(Actions(c.Actions)) + v.SelfValidate(Elements(c.Body)) + v.SelfValidate(Actions(c.Actions)) return v.Err() } @@ -1067,7 +1071,7 @@ func (e Elements) Validate() error { // Validate asserts that fields have valid values. func (e Element) Validate() error { - v := validation.Validator{} + v := validator.Validator{} supportedElementTypes := supportedElementTypes() supportedSizeValues := supportedSizeValues() @@ -1085,14 +1089,14 @@ func (e Element) Validate() error { General requirements for all Element types. ******************************************************************/ - v.MustBeInListIfFieldValNotEmpty(e.Type, "Type", "element", supportedElementTypes, ErrInvalidType) - v.MustBeInListIfFieldValNotEmpty(e.Size, "Size", "element", supportedSizeValues, ErrInvalidFieldValue) - v.MustBeInListIfFieldValNotEmpty(e.Weight, "Weight", "element", supportedWeightValues, ErrInvalidFieldValue) - v.MustBeInListIfFieldValNotEmpty(e.Color, "Color", "element", supportedColorValues, ErrInvalidFieldValue) - v.MustBeInListIfFieldValNotEmpty(e.Spacing, "Spacing", "element", supportedSpacingValues, ErrInvalidFieldValue) - v.MustBeInListIfFieldValNotEmpty(e.Style, "Style", "element", supportedStyleValues, ErrInvalidFieldValue) + v.InListIfFieldValNotEmpty(e.Type, "Type", "element", supportedElementTypes, ErrInvalidType) + v.InListIfFieldValNotEmpty(e.Size, "Size", "element", supportedSizeValues, ErrInvalidFieldValue) + v.InListIfFieldValNotEmpty(e.Weight, "Weight", "element", supportedWeightValues, ErrInvalidFieldValue) + v.InListIfFieldValNotEmpty(e.Color, "Color", "element", supportedColorValues, ErrInvalidFieldValue) + v.InListIfFieldValNotEmpty(e.Spacing, "Spacing", "element", supportedSpacingValues, ErrInvalidFieldValue) + v.InListIfFieldValNotEmpty(e.Style, "Style", "element", supportedStyleValues, ErrInvalidFieldValue) - v.MustBeSuccessfulFuncCall( + v.SuccessfulFuncCall( func() error { return assertElementSupportsStyleValue(e, supportedStyleValues) }, @@ -1112,30 +1116,30 @@ func (e Element) Validate() error { // Columns collection is used by the ColumnSet type. While not required, // the collection should be checked. case e.Type == TypeElementColumnSet: - v.MustSelfValidate(Columns(e.Columns)) + v.SelfValidate(Columns(e.Columns)) // Actions collection is required for ActionSet element type. // https://adaptivecards.io/explorer/ActionSet.html case e.Type == TypeElementActionSet: - v.MustBeNotEmptyCollection("Actions", e.Type, ErrMissingValue, e.Actions) - v.MustSelfValidate(Actions(e.Actions)) + v.NotEmptyCollection("Actions", e.Type, ErrMissingValue, e.Actions) + v.SelfValidate(Actions(e.Actions)) // Items collection is required for Container element type. // https://adaptivecards.io/explorer/Container.html case e.Type == TypeElementContainer: - v.MustBeNotEmptyCollection("Items", e.Type, ErrMissingValue, e.Items) - v.MustSelfValidate(Elements(e.Items)) + v.NotEmptyCollection("Items", e.Type, ErrMissingValue, e.Items) + v.SelfValidate(Elements(e.Items)) // URL is required for Image element type. // https://adaptivecards.io/explorer/Image.html case e.Type == TypeElementImage: - v.MustBeNotEmptyValue(e.URL, "URL", e.Type, ErrMissingValue) + v.NotEmptyValue(e.URL, "URL", e.Type, ErrMissingValue) // Facts collection is required for FactSet element type. // https://adaptivecards.io/explorer/FactSet.html case e.Type == TypeElementFactSet: - v.MustBeNotEmptyCollection("Facts", e.Type, ErrMissingValue, e.Facts) - v.MustSelfValidate(Facts(e.Facts)) + v.NotEmptyCollection("Facts", e.Type, ErrMissingValue, e.Facts) + v.SelfValidate(Facts(e.Facts)) } // Return the last recorded validation error, or nil if no validation @@ -1154,70 +1158,55 @@ func (c Columns) Validate() error { return nil } -// Validate asserts that fields have valid values. -func (c Column) Validate() error { - if c.Type != TypeColumn { - return fmt.Errorf( - "invalid column type %q; expected %q: %w", - c.Type, - TypeColumn, - ErrInvalidType, - ) - } - - switch v := c.Width.(type) { - // Nothing to see here. - case nil: - - // Assert specific fixed keyword values or valid pixel width; all other - // values are invalid. - case string: - v = strings.TrimSpace(v) - matched, _ := regexp.MatchString(ColumnWidthPixelRegex, v) - - switch { - case v == ColumnWidthAuto: - case v == ColumnWidthStretch: - case !matched: +// Validate asserts that the Items collection field for a column contains +// valid values. Special handling is applied since the collection could +// contain nil values. +func (ci ColumnItems) Validate() error { + for _, item := range ci { + if item == nil { return fmt.Errorf( - "invalid pixel width %q; expected value in format %s: %w", - v, - ColumnWidthPixelWidthExample, - ErrInvalidFieldValue, + "card element in Column is nil: %w", + ErrMissingValue, ) } - // Number representing relative width of the column. - case int: - - // Unsupported value. - default: - return fmt.Errorf( - "invalid pixel width %q; "+ - "expected one of keywords %q, int value (e.g., %d) "+ - "or specific pixel width (e.g., %s): %w", - v, - strings.Join([]string{ - ColumnWidthAuto, - ColumnWidthStretch, - }, ","), - 1, - ColumnWidthPixelWidthExample, - ErrInvalidFieldValue, - ) - } - - for _, element := range c.Items { - if err := element.Validate(); err != nil { + if err := item.Validate(); err != nil { return err } } + return nil +} + +// Validate asserts that fields have valid values. +func (c Column) Validate() error { + v := validator.Validator{} + + v.FieldHasSpecificValue( + c.Type, + "type", + TypeColumn, + "column", + ErrInvalidType, + ) + + v.SuccessfulFuncCall( + func() error { return assertColumnWidthValidValues(c) }, + ) + + // Assert that the collection does not contain nil items. + v.NoNilValuesInCollection("Items", c.Type, ErrMissingValue, c.Items) + + // Convert []*Element to ColumnItems so that we can use its Validate() + // method to handle cases where nil values could be present in the + // collection. + v.SelfValidate(ColumnItems(c.Items)) + if c.SelectAction != nil { - return c.SelectAction.Validate() + v.SelfValidate(c.SelectAction) } - return nil + return v.Err() } // Validate asserts that the collection of Fact values are all valid. @@ -1233,20 +1222,20 @@ func (f Facts) Validate() error { // Validate asserts that fields have valid values. func (f Fact) Validate() error { - v := validation.Validator{} + v := validator.Validator{} - v.MustBeNotEmptyValue(f.Title, "Title", "Fact", ErrMissingValue) - v.MustBeNotEmptyValue(f.Value, "Value", "Fact", ErrMissingValue) + v.NotEmptyValue(f.Title, "Title", "Fact", ErrMissingValue) + v.NotEmptyValue(f.Value, "Value", "Fact", ErrMissingValue) return v.Err() } // Validate asserts that fields have valid values. func (m MSTeams) Validate() error { - v := validation.Validator{} + v := validator.Validator{} // If an optional width value is set, assert that it is a valid value. - v.MustBeInListIfFieldValNotEmpty( + v.InListIfFieldValNotEmpty( m.Width, "Width", "MSTeams", @@ -1254,18 +1243,18 @@ func (m MSTeams) Validate() error { ErrInvalidFieldValue, ) - v.MustSelfValidate(Mentions(m.Entities)) + v.SelfValidate(Mentions(m.Entities)) return v.Err() } // Validate asserts that fields have valid values. func (i ISelectAction) Validate() error { - v := validation.Validator{} + v := validator.Validator{} // Some supportedISelectActionValues are restricted to later Adaptive Card // schema versions. - v.MustBeInList( + v.InList( i.Type, "Type", "ISelectAction", @@ -1273,7 +1262,7 @@ func (i ISelectAction) Validate() error { ErrInvalidType, ) - v.MustBeInListIfFieldValNotEmpty( + v.InListIfFieldValNotEmpty( i.Fallback, "Fallback", "ISelectAction", @@ -1282,7 +1271,7 @@ func (i ISelectAction) Validate() error { ) if i.Type == TypeActionOpenURL { - v.MustBeNotEmptyValue(i.URL, "URL", i.Type, ErrMissingValue) + v.NotEmptyValue(i.URL, "URL", i.Type, ErrMissingValue) } return v.Err() @@ -2208,3 +2197,49 @@ func assertCardBodyHasMention(elements []Element, mentions []Mention) error { return nil } + +func assertColumnWidthValidValues(c Column) error { + switch v := c.Width.(type) { + // Nothing to see here. + case nil: + + // Assert specific fixed keyword values or valid pixel width; all other + // values are invalid. + case string: + v = strings.TrimSpace(v) + matched, _ := regexp.MatchString(ColumnWidthPixelRegex, v) + + switch { + case v == ColumnWidthAuto: + case v == ColumnWidthStretch: + case !matched: + return fmt.Errorf( + "invalid pixel width %q; expected value in format %s: %w", + v, + ColumnWidthPixelWidthExample, + ErrInvalidFieldValue, + ) + } + + // Number representing relative width of the column. + case int: + + // Unsupported value. + default: + return fmt.Errorf( + "invalid pixel width %q; "+ + "expected one of keywords %q, int value (e.g., %d) "+ + "or specific pixel width (e.g., %s): %w", + v, + strings.Join([]string{ + ColumnWidthAuto, + ColumnWidthStretch, + }, ","), + 1, + ColumnWidthPixelWidthExample, + ErrInvalidFieldValue, + ) + } + + return nil +} diff --git a/internal/validation/doc.go b/internal/validator/doc.go similarity index 70% rename from internal/validation/doc.go rename to internal/validator/doc.go index d80d009..ee13cbc 100644 --- a/internal/validation/doc.go +++ b/internal/validator/doc.go @@ -6,8 +6,8 @@ // full license information. /* -Package validation provides logic to assist with validation tasks. The logic -is designed so that each subsequent validation step short-circuits after the +Package validator provides logic to assist with validation tasks. The logic is +designed so that each subsequent validation step short-circuits after the first validation failure; only the first validation failure is reported. Credit to Fabrizio Milo for sharing the original implementation: @@ -16,4 +16,4 @@ Credit to Fabrizio Milo for sharing the original implementation: - https://github.com/Mistobaan */ -package validation +package validator diff --git a/internal/validation/validation.go b/internal/validator/validator.go similarity index 66% rename from internal/validation/validation.go rename to internal/validator/validator.go index d06134b..865b980 100644 --- a/internal/validation/validation.go +++ b/internal/validator/validator.go @@ -5,7 +5,7 @@ // Licensed under the MIT License. See LICENSE file in the project root for // full license information. -package validation +package validator import ( "fmt" @@ -32,11 +32,22 @@ type Validator struct { err error } -// MustSelfValidate asserts that each given item can self-validate. +// hasNilValues is a helper function used to determine whether any items in +// the given collection are nil. +func hasNilValues(items []interface{}) bool { + for _, item := range items { + if item == nil { + return true + } + } + return false +} + +// SelfValidate asserts that each given item can self-validate. // // A true value is returned if the validation step passed. A false value is -// returned false if this or a prior validation step failed. -func (v *Validator) MustSelfValidate(items ...Validater) bool { +// returned if this or a prior validation step failed. +func (v *Validator) SelfValidate(items ...Validater) bool { if v.err != nil { return false } @@ -49,31 +60,31 @@ func (v *Validator) MustSelfValidate(items ...Validater) bool { return true } -// MustSelfValidateIfXEqualsY asserts that each given item can self-validate -// if value x is equal to y. +// SelfValidateIfXEqualsY asserts that each given item can self-validate if +// value x is equal to y. // // A true value is returned if the validation step passed. A false value is // returned false if this or a prior validation step failed. -func (v *Validator) MustSelfValidateIfXEqualsY(x string, y string, items ...Validater) bool { +func (v *Validator) SelfValidateIfXEqualsY(x string, y string, items ...Validater) bool { if v.err != nil { return false } if x == y { - v.MustSelfValidate(items...) + v.SelfValidate(items...) } return true } -// MustBeFieldHasSpecificValue asserts that fieldVal is reqVal. fieldValDesc +// FieldHasSpecificValue asserts that fieldVal is reqVal. fieldValDesc // describes the field value being validated (e.g., "Type") and typeDesc // describes the specific struct or value type whose field we are validating // (e.g., "Element"). // // A true value is returned if the validation step passed. A false value is // returned if this or a prior validation step failed. -func (v *Validator) MustBeFieldHasSpecificValue( +func (v *Validator) FieldHasSpecificValue( fieldVal string, fieldValDesc string, reqVal string, @@ -103,14 +114,14 @@ func (v *Validator) MustBeFieldHasSpecificValue( } } -// MustBeFieldHasSpecificValueIfFieldNotEmpty asserts that fieldVal is reqVal -// unless fieldVal is empty. fieldValDesc describes the field value being -// validated (e.g., "Type") and typeDesc describes the specific struct or -// value type whose field we are validating (e.g., "Element"). +// FieldHasSpecificValueIfFieldNotEmpty asserts that fieldVal is reqVal unless +// fieldVal is empty. fieldValDesc describes the field value being validated +// (e.g., "Type") and typeDesc describes the specific struct or value type +// whose field we are validating (e.g., "Element"). // // A true value is returned if the validation step passed. A false value is // returned if this or a prior validation step failed. -func (v *Validator) MustBeFieldHasSpecificValueIfFieldNotEmpty( +func (v *Validator) FieldHasSpecificValueIfFieldNotEmpty( fieldVal string, fieldValDesc string, reqVal string, @@ -123,7 +134,7 @@ func (v *Validator) MustBeFieldHasSpecificValueIfFieldNotEmpty( return false case fieldVal != "": - return v.MustBeFieldHasSpecificValue( + return v.FieldHasSpecificValue( fieldVal, fieldValDesc, reqVal, @@ -136,14 +147,14 @@ func (v *Validator) MustBeFieldHasSpecificValueIfFieldNotEmpty( } } -// MustBeNotEmptyValue asserts that fieldVal is not empty. fieldValDesc -// describes the field value being validated (e.g., "Type") and typeDesc -// describes the specific struct or value type whose field we are validating -// (e.g., "Element"). +// NotEmptyValue asserts that fieldVal is not empty. fieldValDesc describes +// the field value being validated (e.g., "Type") and typeDesc describes the +// specific struct or value type whose field we are validating (e.g., +// "Element"). // // A true value is returned if the validation step passed. A false value is // returned if this or a prior validation step failed. -func (v *Validator) MustBeNotEmptyValue(fieldVal string, fieldValDesc string, typeDesc string, baseErr error) bool { +func (v *Validator) NotEmptyValue(fieldVal string, fieldValDesc string, typeDesc string, baseErr error) bool { if v.err != nil { return false } @@ -159,15 +170,15 @@ func (v *Validator) MustBeNotEmptyValue(fieldVal string, fieldValDesc string, ty return true } -// MustBeInList reports whether fieldVal is in validVals. fieldValDesc -// describes the field value being validated (e.g., "Type") and typeDesc -// describes the specific struct or value type whose field we are validating -// (e.g., "Element"). +// InList reports whether fieldVal is in validVals. fieldValDesc describes the +// field value being validated (e.g., "Type") and typeDesc describes the +// specific struct or value type whose field we are validating (e.g., +// "Element"). // // A true value is returned if fieldVal is is in validVals. A false value is // returned if a prior validation step failed or if fieldVal is empty or is // not in validVals. -func (v *Validator) MustBeInList(fieldVal string, fieldValDesc string, typeDesc string, validVals []string, baseErr error) bool { +func (v *Validator) InList(fieldVal string, fieldValDesc string, typeDesc string, validVals []string, baseErr error) bool { switch { case v.err != nil: return false @@ -204,7 +215,7 @@ func (v *Validator) MustBeInList(fieldVal string, fieldValDesc string, typeDesc } } -// MustBeInListIfFieldValNotEmpty reports whether fieldVal is in validVals if +// InListIfFieldValNotEmpty reports whether fieldVal is in validVals if // fieldVal is not empty. fieldValDesc describes the field value being // validated (e.g., "Type") and typeDesc describes the specific struct or // value type whose field we are validating (e.g., "Element"). @@ -212,7 +223,7 @@ func (v *Validator) MustBeInList(fieldVal string, fieldValDesc string, typeDesc // A true value is returned if fieldVal is empty or is in validVals. A false // value is returned if a prior validation step failed or if fieldVal is not // empty and is not in validVals. -func (v *Validator) MustBeInListIfFieldValNotEmpty(fieldVal string, fieldValDesc string, typeDesc string, validVals []string, baseErr error) bool { +func (v *Validator) InListIfFieldValNotEmpty(fieldVal string, fieldValDesc string, typeDesc string, validVals []string, baseErr error) bool { switch { case v.err != nil: return false @@ -246,15 +257,15 @@ func (v *Validator) MustBeInListIfFieldValNotEmpty(fieldVal string, fieldValDesc } } -// MustBeFieldInListIfTypeValIs reports whether fieldVal is in validVals if -// fieldVal is not empty. fieldValDesc describes the field value being -// validated (e.g., "Type") and typeDesc describes the specific struct or -// value type whose field we are validating (e.g., "Element"). +// FieldInListIfTypeValIs reports whether fieldVal is in validVals if fieldVal +// is not empty. fieldValDesc describes the field value being validated (e.g., +// "Type") and typeDesc describes the specific struct or value type whose +// field we are validating (e.g., "Element"). // // A true value is returned if fieldVal is empty or is in validVals. A false // value is returned if a prior validation step failed or if fieldVal is not // empty and is not in validVals. -// func (v *Validator) MustBeFieldInListIfTypeValIs( +// func (v *Validator) FieldInListIfTypeValIs( // fieldVal string, // fieldDesc string, // typeVal string, @@ -294,7 +305,7 @@ func (v *Validator) MustBeInListIfFieldValNotEmpty(fieldVal string, fieldValDesc // } // } -// MustBeNotEmptyCollection asserts that the specified items collection is not +// NotEmptyCollection asserts that the specified items collection is not // empty. fieldValueDesc describes the field for this collection being // validated (e.g., "Facts") and typeDesc describes the specific struct or // value type whose field we are validating (e.g., "Element"). @@ -302,7 +313,7 @@ func (v *Validator) MustBeInListIfFieldValNotEmpty(fieldVal string, fieldValDesc // A true value is returned if the collection is not empty. A false value is // returned if a prior validation step failed or if the items collection is // empty. -func (v *Validator) MustBeNotEmptyCollection(fieldValueDesc string, typeDesc string, baseErr error, items ...interface{}) bool { +func (v *Validator) NotEmptyCollection(fieldValueDesc string, typeDesc string, baseErr error, items ...interface{}) bool { if v.err != nil { return false } @@ -328,7 +339,46 @@ func (v *Validator) MustBeNotEmptyCollection(fieldValueDesc string, typeDesc str return true } -// MustBeNotEmptyCollectionIfFieldValNotEmpty asserts that the specified items +// NoNilValuesInCollection asserts that the specified items collection does +// not contain any nil values. fieldValueDesc describes the field for this +// collection being validated (e.g., "Facts") and typeDesc describes the +// specific struct or value type whose field we are validating (e.g., +// "Element"). +// +// A true value is returned if the collection does not contain any nil values +// (even if the collection itself has no values). A false value is returned if +// a prior validation step failed or if any items in the collection are nil. +func (v *Validator) NoNilValuesInCollection(fieldValueDesc string, typeDesc string, baseErr error, items ...interface{}) bool { + if v.err != nil { + return false + } + + switch { + case hasNilValues(items): + switch { + case baseErr != nil: + v.err = fmt.Errorf( + "required %s collection contains nil values for %s: %w", + fieldValueDesc, + typeDesc, + baseErr, + ) + default: + v.err = fmt.Errorf( + "required %s collection contains nil values for for %s", + fieldValueDesc, + typeDesc, + ) + } + + return false + + default: + return true + } +} + +// NotEmptyCollectionIfFieldValNotEmpty asserts that the specified items // collection is not empty if fieldVal is not empty. fieldValueDesc describes // the field for this collection being validated (e.g., "Facts") and typeDesc // describes the specific struct or value type whose field we are validating @@ -337,7 +387,7 @@ func (v *Validator) MustBeNotEmptyCollection(fieldValueDesc string, typeDesc str // A true value is returned if the collection is not empty. A false value is // returned if a prior validation step failed or if the items collection is // empty. -func (v *Validator) MustBeNotEmptyCollectionIfFieldValNotEmpty( +func (v *Validator) NotEmptyCollectionIfFieldValNotEmpty( fieldVal string, fieldValueDesc string, typeDesc string, @@ -373,12 +423,12 @@ func (v *Validator) MustBeNotEmptyCollectionIfFieldValNotEmpty( } } -// MustBeSuccessfulFuncCall accepts fn, a function that returns an error. fn -// is called in order to determine validation results. +// SuccessfulFuncCall accepts fn, a function that returns an error. fn is +// called in order to determine validation results. // // A true value is returned if fn was successful. A false value is returned if // a prior validation step failed or if fn returned an error. -func (v *Validator) MustBeSuccessfulFuncCall(fn func() error) bool { +func (v *Validator) SuccessfulFuncCall(fn func() error) bool { if v.err != nil { return false }