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