Skip to content
This repository was archived by the owner on Jan 9, 2026. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/en/pact-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,8 @@ pact> (str-to-int "123456")
123456
pact> (str-to-int 64 "q80")
43981
pact> (str-to-int 10 "-1234")
-1234
```


Expand Down
12 changes: 10 additions & 2 deletions src/Pact/Native.hs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ strToIntDef = defRNative "str-to-int" strToInt
["(str-to-int 16 \"abcdef123456\")"
,"(str-to-int \"123456\")"
,"(str-to-int 64 \"q80\")"
,"(str-to-int 10 \"-1234\")"
]
"Compute the integer value of STR-VAL in base 10, or in BASE if specified. \
\STR-VAL can be up to 512 chars in length. \
Expand Down Expand Up @@ -1296,7 +1297,7 @@ txHash i as = argsError i as
--
-- e.g.
-- -- hexadecimal to decimal
-- baseStrToInt 10 "abcdef123456" = 188900967593046
-- baseStrToInt 16 "abcdef123456" = 188900967593046
--
baseStrToInt :: Integer -> Text -> Either Text Integer
baseStrToInt base t =
Expand All @@ -1305,8 +1306,15 @@ baseStrToInt base t =
else
if T.null t
then Left $ "empty text: " `T.append` asString t
else foldM go 0 $ T.unpack t
else
let invalidChars = filter (not. Char.isHexDigit) (T.unpack absPart) in
if null invalidChars
then fmap (sign *) $ foldM go 0 $ T.unpack absPart
else Left $ "text contains invalid characters: " <> T.pack invalidChars
where
(sign, absPart) = case T.stripPrefix "-" t of
Nothing -> (1, t)
Just suffix -> (-1, suffix)
go :: Integer -> Char -> Either Text Integer
go acc c' =
let val = fromIntegral . Char.digitToInt $ c'
Expand Down
4 changes: 3 additions & 1 deletion tests/AnalyzeSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2304,11 +2304,12 @@ spec = describe "analyze" $ do
describe "str-to-int" $ do
describe "without specified base" $ do
describe "concrete string" $ do
describe "valid inputs" $
describe "str-to-int-valid-inputs" $
let code =
[text|
(defun test:bool ()
(enforce (= (str-to-int "5") 5) "")
(enforce (= (str-to-int "-5") -5) "")
(enforce (= (str-to-int "11111111111111111111111") 11111111111111111111111) "")
)
|]
Expand Down Expand Up @@ -2340,6 +2341,7 @@ spec = describe "analyze" $ do
[text|
(defun test:bool ()
(enforce (= (str-to-int 10 "5") 5) "")
(enforce (= (str-to-int 10 "-5") -5) "")
(enforce (= (str-to-int 8 "10") 8) "")
)
|]
Expand Down