github.com/wI2L/jettison@v0.7.5-0.20230106001914-c70014c6417a/number.go (about)

     1  package jettison
     2  
     3  // isValidNumber returns whether s is a valid JSON
     4  // number literal. Taken from encoding/json.
     5  func isValidNumber(s string) bool {
     6  	// This function implements the JSON numbers grammar.
     7  	// See https://tools.ietf.org/html/rfc7159#section-6
     8  	// and https://www.json.org/img/number.png.
     9  	if s == "" {
    10  		return false
    11  	}
    12  	// Optional minus sign.
    13  	if s[0] == '-' {
    14  		s = s[1:]
    15  		if s == "" {
    16  			return false
    17  		}
    18  	}
    19  	// Digits.
    20  	switch {
    21  	default:
    22  		return false
    23  	case s[0] == '0':
    24  		s = s[1:]
    25  	case '1' <= s[0] && s[0] <= '9':
    26  		s = s[1:]
    27  		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
    28  			s = s[1:]
    29  		}
    30  	}
    31  	// Dot followed by one or more digits.
    32  	if len(s) >= 2 && s[0] == '.' && '0' <= s[1] && s[1] <= '9' {
    33  		s = s[2:]
    34  		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
    35  			s = s[1:]
    36  		}
    37  	}
    38  	// e or E followed by an optional - or + sign
    39  	// and one or more digits.
    40  	if len(s) >= 2 && (s[0] == 'e' || s[0] == 'E') {
    41  		s = s[1:]
    42  		if s[0] == '+' || s[0] == '-' {
    43  			s = s[1:]
    44  			if s == "" {
    45  				return false
    46  			}
    47  		}
    48  		for len(s) > 0 && '0' <= s[0] && s[0] <= '9' {
    49  			s = s[1:]
    50  		}
    51  	}
    52  	// Make sure we are at the end.
    53  	return s == ""
    54  }