42 lines
1.5 KiB
Haskell
42 lines
1.5 KiB
Haskell
module RustClient (
|
|
callRustMessage,
|
|
callRustSummary,
|
|
) where
|
|
|
|
import Control.Exception (bracket)
|
|
import Foreign.C.String (CString, peekCString, withCString)
|
|
import Foreign.C.Types (CInt (..))
|
|
import Foreign.Marshal.Alloc (alloca)
|
|
import Foreign.Ptr (Ptr, nullPtr)
|
|
import Foreign.Storable (peek)
|
|
import Interop.Shared (Summary, SharedStats, summaryFromSharedStats)
|
|
|
|
foreign import ccall unsafe "rust_compute_stats"
|
|
rustComputeStats :: CInt -> CInt -> Ptr SharedStats -> IO CInt
|
|
|
|
foreign import ccall unsafe "rust_make_message"
|
|
rustMakeMessage :: CString -> CInt -> CInt -> IO CString
|
|
|
|
foreign import ccall unsafe "rust_free_string"
|
|
rustFreeString :: CString -> IO ()
|
|
|
|
callRustSummary :: Int -> Int -> IO Summary
|
|
callRustSummary left right =
|
|
alloca $ \outStats -> do
|
|
status <- rustComputeStats (fromIntegral left) (fromIntegral right) outStats
|
|
if status /= 0
|
|
then fail ("rustComputeStats returned status " ++ show status)
|
|
else summaryFromSharedStats <$> peek outStats
|
|
|
|
callRustMessage :: String -> Int -> Int -> IO String
|
|
callRustMessage name left right =
|
|
withCString name $ \namePtr -> do
|
|
messagePtr <- rustMakeMessage namePtr (fromIntegral left) (fromIntegral right)
|
|
if messagePtr == nullPtr
|
|
then fail "rustMakeMessage returned a null pointer"
|
|
else
|
|
bracket
|
|
(pure messagePtr)
|
|
rustFreeString
|
|
peekCString
|