github.com/bytedance/go-tagexpr/v2@v2.9.8/validator/func.go (about)

     1  package validator
     2  
     3  import (
     4  	"errors"
     5  	"regexp"
     6  
     7  	"github.com/nyaruka/phonenumbers"
     8  
     9  	"github.com/bytedance/go-tagexpr/v2"
    10  )
    11  
    12  // ErrInvalidWithoutMsg verification error without error message.
    13  var ErrInvalidWithoutMsg = errors.New("")
    14  
    15  // MustRegFunc registers validator function expression.
    16  // NOTE:
    17  //
    18  //	panic if exist error;
    19  //	example: phone($) or phone($,'CN');
    20  //	If @force=true, allow to cover the existed same @funcName;
    21  //	The go number types always are float64;
    22  //	The go string types always are string.
    23  func MustRegFunc(funcName string, fn func(args ...interface{}) error, force ...bool) {
    24  	err := RegFunc(funcName, fn, force...)
    25  	if err != nil {
    26  		panic(err)
    27  	}
    28  }
    29  
    30  // RegFunc registers validator function expression.
    31  // NOTE:
    32  //
    33  //	example: phone($) or phone($,'CN');
    34  //	If @force=true, allow to cover the existed same @funcName;
    35  //	The go number types always are float64;
    36  //	The go string types always are string.
    37  func RegFunc(funcName string, fn func(args ...interface{}) error, force ...bool) error {
    38  	return tagexpr.RegFunc(funcName, func(args ...interface{}) interface{} {
    39  		err := fn(args...)
    40  		if err == nil {
    41  			// nil defaults to false, so returns true
    42  			return true
    43  		}
    44  		return err
    45  	}, force...)
    46  }
    47  
    48  func init() {
    49  	var pattern = "^([A-Za-z0-9_\\-\\.\u4e00-\u9fa5])+\\@([A-Za-z0-9_\\-\\.])+\\.([A-Za-z]{2,8})$"
    50  	emailRegexp := regexp.MustCompile(pattern)
    51  	MustRegFunc("email", func(args ...interface{}) error {
    52  		if len(args) != 1 {
    53  			return errors.New("number of parameters of email function is not one")
    54  		}
    55  		s, ok := args[0].(string)
    56  		if !ok {
    57  			return errors.New("parameter of email function is not string type")
    58  		}
    59  		matched := emailRegexp.MatchString(s)
    60  		if !matched {
    61  			// return ErrInvalidWithoutMsg
    62  			return errors.New("email format is incorrect")
    63  		}
    64  		return nil
    65  	}, true)
    66  }
    67  
    68  func init() {
    69  	// phone: defaultRegion is 'CN'
    70  	MustRegFunc("phone", func(args ...interface{}) error {
    71  		var numberToParse, defaultRegion string
    72  		var ok bool
    73  		switch len(args) {
    74  		default:
    75  			return errors.New("the number of parameters of phone function is not one or two")
    76  		case 2:
    77  			defaultRegion, ok = args[1].(string)
    78  			if !ok {
    79  				return errors.New("the 2nd parameter of phone function is not string type")
    80  			}
    81  			fallthrough
    82  		case 1:
    83  			numberToParse, ok = args[0].(string)
    84  			if !ok {
    85  				return errors.New("the 1st parameter of phone function is not string type")
    86  			}
    87  		}
    88  		if defaultRegion == "" {
    89  			defaultRegion = "CN"
    90  		}
    91  		num, err := phonenumbers.Parse(numberToParse, defaultRegion)
    92  		if err != nil {
    93  			return err
    94  		}
    95  		matched := phonenumbers.IsValidNumber(num)
    96  		if !matched {
    97  			// return ErrInvalidWithoutMsg
    98  			return errors.New("phone format is incorrect")
    99  		}
   100  		return nil
   101  	}, true)
   102  }