Skip to content

Commit

Permalink
DRY up ignore related conditionals (#103)
Browse files Browse the repository at this point in the history
  • Loading branch information
rodaine authored Feb 26, 2024
1 parent 6897c76 commit e2171c5
Showing 1 changed file with 42 additions and 31 deletions.
73 changes: 42 additions & 31 deletions internal/evaluator/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,18 +207,12 @@ func (bldr *Builder) buildField(
Descriptor: fieldDescriptor,
Required: fieldConstraints.GetRequired(),
IgnoreEmpty: fieldDescriptor.HasPresence() ||
fieldConstraints.GetIgnoreEmpty() ||
fieldConstraints.GetIgnore() == validate.Ignore_IGNORE_IF_UNPOPULATED ||
fieldConstraints.GetIgnore() == validate.Ignore_IGNORE_IF_DEFAULT_VALUE,
IgnoreDefault: fieldDescriptor.HasPresence() && fieldConstraints.GetIgnore() == validate.Ignore_IGNORE_IF_DEFAULT_VALUE,
bldr.shouldIgnoreEmpty(fieldConstraints),
IgnoreDefault: fieldDescriptor.HasPresence() &&
bldr.shouldIgnoreDefault(fieldConstraints),
}
if fld.IgnoreDefault {
if fieldDescriptor.Kind() == protoreflect.MessageKind && fieldDescriptor.Cardinality() != protoreflect.Repeated {
msg := dynamicpb.NewMessage(fieldDescriptor.Message())
fld.Zero = protoreflect.ValueOfMessage(msg)
} else {
fld.Zero = fieldDescriptor.Default()
}
fld.Zero = bldr.zeroValue(fieldDescriptor, false)
}
err := bldr.buildValue(fieldDescriptor, fieldConstraints, false, &fld.Value, cache)
return fld, err
Expand Down Expand Up @@ -266,21 +260,9 @@ func (bldr *Builder) processIgnoreEmpty(
) error {
// the only time we need to ignore empty on a value is if it's evaluating a
// field item (repeated element or map key/value).
val.IgnoreEmpty = forItems && (constraints.GetIgnoreEmpty() ||
constraints.GetIgnore() == validate.Ignore_IGNORE_IF_UNPOPULATED ||
constraints.GetIgnore() == validate.Ignore_IGNORE_IF_DEFAULT_VALUE)
switch {
case !val.IgnoreEmpty:
// only need the zero value for checking ignore_empty constraint
return nil
case fdesc.IsList():
msg := dynamicpb.NewMessage(fdesc.ContainingMessage())
val.Zero = msg.Get(fdesc).List().NewElement()
case fdesc.Kind() == protoreflect.MessageKind:
msg := dynamicpb.NewMessage(fdesc.Message())
val.Zero = protoreflect.ValueOfMessage(msg)
default:
val.Zero = fdesc.Default()
val.IgnoreEmpty = forItems && bldr.shouldIgnoreEmpty(constraints)
if val.IgnoreEmpty {
val.Zero = bldr.zeroValue(fdesc, forItems)
}
return nil
}
Expand Down Expand Up @@ -320,9 +302,9 @@ func (bldr *Builder) processEmbeddedMessage(
cache MessageCache,
) error {
if fdesc.Kind() != protoreflect.MessageKind ||
rules.GetSkipped() ||
rules.GetIgnore() == validate.Ignore_IGNORE_ALWAYS ||
fdesc.IsMap() || (fdesc.IsList() && !forItems) {
bldr.shouldSkip(rules) ||
fdesc.IsMap() ||
(fdesc.IsList() && !forItems) {
return nil
}

Expand All @@ -345,9 +327,9 @@ func (bldr *Builder) processWrapperConstraints(
cache MessageCache,
) error {
if fdesc.Kind() != protoreflect.MessageKind ||
rules.GetSkipped() ||
rules.GetIgnore() == validate.Ignore_IGNORE_ALWAYS ||
fdesc.IsMap() || (fdesc.IsList() && !forItems) {
bldr.shouldSkip(rules) ||
fdesc.IsMap() ||
(fdesc.IsList() && !forItems) {
return nil
}

Expand Down Expand Up @@ -486,6 +468,35 @@ func (bldr *Builder) processRepeatedConstraints(
return nil
}

func (bldr *Builder) shouldSkip(constraints *validate.FieldConstraints) bool {
return constraints.GetSkipped() ||
constraints.GetIgnore() == validate.Ignore_IGNORE_ALWAYS
}

func (bldr *Builder) shouldIgnoreEmpty(constraints *validate.FieldConstraints) bool {
return constraints.GetIgnoreEmpty() ||
constraints.GetIgnore() == validate.Ignore_IGNORE_IF_UNPOPULATED ||
constraints.GetIgnore() == validate.Ignore_IGNORE_IF_DEFAULT_VALUE
}

func (bldr *Builder) shouldIgnoreDefault(constraints *validate.FieldConstraints) bool {
return constraints.GetIgnore() == validate.Ignore_IGNORE_IF_DEFAULT_VALUE
}

func (bldr *Builder) zeroValue(fdesc protoreflect.FieldDescriptor, forItems bool) protoreflect.Value {
switch {
case forItems && fdesc.IsList():
msg := dynamicpb.NewMessage(fdesc.ContainingMessage())
return msg.Get(fdesc).List().NewElement()
case fdesc.Kind() == protoreflect.MessageKind &&
fdesc.Cardinality() != protoreflect.Repeated:
msg := dynamicpb.NewMessage(fdesc.Message())
return protoreflect.ValueOfMessage(msg)
default:
return fdesc.Default()
}
}

type MessageCache map[protoreflect.MessageDescriptor]*message

func (c MessageCache) Clone() MessageCache {
Expand Down

0 comments on commit e2171c5

Please sign in to comment.