Merge pull request #292945 from adisbladis/lib-toint

lib.toInt/toIntBase10: Make more efficient by hoisting up internal strings into higher scope
This commit is contained in:
Silvan Mosberger 2024-03-06 19:42:52 +01:00 committed by GitHub
commit 727958ee36
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1038,30 +1038,32 @@ rec {
toInt "3.14"
=> error: floating point JSON numbers are not supported
*/
toInt = str:
toInt =
let
matchStripInput = match "[[:space:]]*(-?[[:digit:]]+)[[:space:]]*";
matchLeadingZero = match "0[[:digit:]]+";
in
str:
let
# RegEx: Match any leading whitespace, possibly a '-', one or more digits,
# and finally match any trailing whitespace.
strippedInput = match "[[:space:]]*(-?[[:digit:]]+)[[:space:]]*" str;
strippedInput = matchStripInput str;
# RegEx: Match a leading '0' then one or more digits.
isLeadingZero = match "0[[:digit:]]+" (head strippedInput) == [];
isLeadingZero = matchLeadingZero (head strippedInput) == [];
# Attempt to parse input
parsedInput = fromJSON (head strippedInput);
generalError = "toInt: Could not convert ${escapeNixString str} to int.";
octalAmbigError = "toInt: Ambiguity in interpretation of ${escapeNixString str}"
+ " between octal and zero padded integer.";
in
# Error on presence of non digit characters.
if strippedInput == null
then throw generalError
# Error on presence of leading zero/octal ambiguity.
else if isLeadingZero
then throw octalAmbigError
then throw "toInt: Ambiguity in interpretation of ${escapeNixString str} between octal and zero padded integer."
# Error if parse function fails.
else if !isInt parsedInput
then throw generalError
@ -1089,15 +1091,20 @@ rec {
toIntBase10 "3.14"
=> error: floating point JSON numbers are not supported
*/
toIntBase10 = str:
toIntBase10 =
let
matchStripInput = match "[[:space:]]*0*(-?[[:digit:]]+)[[:space:]]*";
matchZero = match "0+";
in
str:
let
# RegEx: Match any leading whitespace, then match any zero padding,
# capture possibly a '-' followed by one or more digits,
# and finally match any trailing whitespace.
strippedInput = match "[[:space:]]*0*(-?[[:digit:]]+)[[:space:]]*" str;
strippedInput = matchStripInput str;
# RegEx: Match at least one '0'.
isZero = match "0+" (head strippedInput) == [];
isZero = matchZero (head strippedInput) == [];
# Attempt to parse input
parsedInput = fromJSON (head strippedInput);