github.com/go-email-validator/go-email-validator@v0.0.0-20230409163946-b8b9e6a0552e/pkg/ev/decorator_cache.go (about)

     1  package ev
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/go-email-validator/go-email-validator/pkg/ev/evcache"
     6  	"github.com/go-email-validator/go-email-validator/pkg/ev/utils"
     7  	"github.com/go-email-validator/go-email-validator/pkg/log"
     8  	"go.uber.org/zap"
     9  )
    10  
    11  // CacheKeyGetter is type for key generators
    12  // To use complex keys you can use https://github.com/vmihailenco/msgpack/
    13  type CacheKeyGetter func(input Input, results ...ValidationResult) interface{}
    14  
    15  // EmailCacheKeyGetter generates key as full email
    16  func EmailCacheKeyGetter(input Input, _ ...ValidationResult) interface{} {
    17  	return input.Email().String()
    18  }
    19  
    20  // DomainCacheKeyGetter generates key as domain
    21  func DomainCacheKeyGetter(input Input, _ ...ValidationResult) interface{} {
    22  	return input.Email().Domain()
    23  }
    24  
    25  // NewCacheDecorator instantiates cache decorator
    26  func NewCacheDecorator(validator Validator, cache evcache.Interface, getKey CacheKeyGetter) Validator {
    27  	if getKey == nil {
    28  		getKey = EmailCacheKeyGetter
    29  	}
    30  
    31  	return &cacheDecorator{
    32  		validator: validator,
    33  		cache:     cache,
    34  		getKey:    getKey,
    35  	}
    36  }
    37  
    38  type cacheDecorator struct {
    39  	validator Validator
    40  	cache     evcache.Interface
    41  	getKey    CacheKeyGetter
    42  }
    43  
    44  func (c *cacheDecorator) GetDeps() []ValidatorName {
    45  	return c.validator.GetDeps()
    46  }
    47  
    48  func (c *cacheDecorator) Validate(input Input, results ...ValidationResult) (result ValidationResult) {
    49  	key := c.getKey(input, results...)
    50  	resultInterface, err := c.cache.Get(key)
    51  	if err == nil && resultInterface != nil {
    52  		result = *resultInterface.(*ValidationResult)
    53  	} else {
    54  		result = c.validator.Validate(input, results...)
    55  		if err := c.cache.Set(key, result); err != nil {
    56  			log.Logger().Error(fmt.Sprintf("cache decorator %v", err),
    57  				zap.String("validator", utils.StructName(c.validator)),
    58  				zap.String("key", fmt.Sprint(key)),
    59  				zap.String("email", input.Email().String()),
    60  				zap.String("results", fmt.Sprint(results)),
    61  			)
    62  		}
    63  	}
    64  
    65  	return result
    66  }