diff options
author | Jacob Abel <jacobabel@nullpo.dev> | 2022-07-08 19:37:45 -0400 |
---|---|---|
committer | Jacob Abel <jacobabel@nullpo.dev> | 2022-10-23 17:50:24 -0400 |
commit | 39a4ab78a1245eb45d333fc14ec56f3a8f045986 (patch) | |
tree | fd264453068cd9be8e1d9445d3105954ac0d5173 /lib/strings.nix | |
parent | 3d196a5f2a72595b14c439a9b4aba7737c0f1ebe (diff) |
lib/strings: Refactor toInt into toInt and toIntBase10
Diffstat (limited to 'lib/strings.nix')
-rw-r--r-- | lib/strings.nix | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/lib/strings.nix b/lib/strings.nix index c6269e755e2a1..368ec786d6703 100644 --- a/lib/strings.nix +++ b/lib/strings.nix @@ -783,26 +783,74 @@ rec { else false; - /* Parse a string as an int. + /* Parse a string as an int. Does not support parsing of integers with preceding zero due to + ambiguity between zero-padded and octal numbers. Type: string -> int Example: + toInt "1337" => 1337 + toInt "-4" => -4 + toInt " 123 " => 123 + toInt "00024" - => 24 + => error: [json.exception.parse_error.101] parse error at line 1, column 2: syntax error + while parsing value - unexpected number literal; expected end of input + toInt "3.14" => error: floating point JSON numbers are not supported */ # Obviously, it is a bit hacky to use fromJSON this way. toInt = str: let - # RegEx: Match any leading whitespace, then any zero padding, and capture any remaining + # RegEx: Match any leading whitespace, then any digits, and finally match any trailing + # whitespace. + strippedInput = match "[[:space:]]*([[:digit:]]+)[[:space:]]*" str; + + # RegEx: Match any leading whitespace, then a leading '0', then at least one digit following + # after, and finally match any trailing whitespace. + isLeadingZero = match "[[:space:]]*0[[:digit:]]+[[:space:]]*" str == []; + + # Attempt to parse input + parsedInput = fromJSON (elemAt strippedInput 0); + in + if isLeadingZero + then throw "Ambiguity in ${str} between octal and zero padded integer." + else if strippedInput != null && isInt parsedInput + then parsedInput + else throw "Could not convert ${str} to int."; + + + /* Parse a string as a base 10 int. This supports parsing of zero-padded integers. + + Type: string -> int + + Example: + toIntBase10 "1337" + => 1337 + + toIntBase10 "-4" + => -4 + + toIntBase10 " 123 " + => 123 + + toIntBase10 "00024" + => 24 + + toIntBase10 "3.14" + => error: floating point JSON numbers are not supported + */ + # Obviously, it is a bit hacky to use fromJSON this way. + toIntBase10 = str: + let + # RegEx: Match any leading whitespace, then match any zero padding, capture any remaining # digits after that, and finally match any trailing whitespace. strippedInput = match "[[:space:]]*0*([[:digit:]]+)[[:space:]]*" str; |