2026-02-19 13:44:16 +00:00
|
|
|
-- TODO automate this sort of high level wrapper boilerplate
|
|
|
|
|
-- or look at upstream plans: https://github.com/well-typed/hs-bindgen/issues?q=state%3Aopen%20label%3A%22highlevel%22
|
|
|
|
|
module GarnetRs.Wrapped (
|
|
|
|
|
T (..),
|
|
|
|
|
Shape (..),
|
2026-02-19 20:44:04 +00:00
|
|
|
BTree (..),
|
2026-02-19 13:44:16 +00:00
|
|
|
hello,
|
|
|
|
|
helloStruct,
|
|
|
|
|
helloShape,
|
2026-02-19 15:26:27 +00:00
|
|
|
add,
|
2026-02-19 20:44:04 +00:00
|
|
|
sumTree,
|
2026-02-19 13:44:16 +00:00
|
|
|
) where
|
|
|
|
|
|
2026-02-19 21:18:37 +00:00
|
|
|
import Control.Monad.Cont
|
|
|
|
|
import Control.Monad.Trans
|
2026-02-19 13:44:16 +00:00
|
|
|
import Data.ByteString
|
2026-02-19 21:18:37 +00:00
|
|
|
import Data.Function
|
2026-02-19 13:44:16 +00:00
|
|
|
import Data.Word
|
|
|
|
|
import Foreign
|
|
|
|
|
import Foreign.C
|
|
|
|
|
import GarnetRs qualified as Raw
|
|
|
|
|
import GarnetRs.Safe qualified as Raw
|
|
|
|
|
import HsBindgen.Runtime.PtrConst
|
|
|
|
|
|
|
|
|
|
data T = T
|
|
|
|
|
{ a :: Bool
|
|
|
|
|
, b :: Word8
|
|
|
|
|
}
|
|
|
|
|
convertT :: T -> Raw.T
|
2026-02-19 16:26:10 +00:00
|
|
|
convertT T{a, b} = Raw.T{a = fromBool a, b}
|
2026-02-19 13:44:16 +00:00
|
|
|
|
|
|
|
|
data Shape
|
|
|
|
|
= Circle CDouble
|
|
|
|
|
| Rectangle CDouble CDouble
|
|
|
|
|
convertShape :: Shape -> Raw.Shape
|
|
|
|
|
convertShape = \case
|
2026-02-19 16:17:29 +00:00
|
|
|
Circle r -> Raw.Shape Raw.Circle $ Raw.set_shape_body_circle $ Raw.Circle_Body r
|
|
|
|
|
Rectangle w h -> Raw.Shape Raw.Rectangle $ Raw.set_shape_body_rectangle $ Raw.Rectangle_Body w h
|
2026-02-19 13:44:16 +00:00
|
|
|
|
2026-02-19 20:44:04 +00:00
|
|
|
data BTree a
|
|
|
|
|
= Leaf a
|
|
|
|
|
| Fork (BTree a) (BTree a)
|
2026-02-19 21:11:58 +00:00
|
|
|
withBTree :: BTree Int64 -> (Raw.BTreeC -> IO a) -> IO a
|
2026-02-19 21:18:37 +00:00
|
|
|
withBTree =
|
|
|
|
|
runContT . fix \f -> \case
|
|
|
|
|
Leaf v -> pure $ Raw.BTreeC Raw.Leaf $ Raw.set_bTreeC_body_leaf $ Raw.Leaf_Body v
|
|
|
|
|
Fork l r -> do
|
|
|
|
|
lRaw <- f l
|
|
|
|
|
rRaw <- f r
|
|
|
|
|
lPtr <- ContT alloca
|
|
|
|
|
rPtr <- ContT alloca
|
|
|
|
|
lift $ poke lPtr lRaw >> poke rPtr rRaw
|
|
|
|
|
pure . Raw.BTreeC Raw.Fork . Raw.set_bTreeC_body_fork $
|
|
|
|
|
Raw.Fork_Body (unsafeFromPtr lPtr) (unsafeFromPtr rPtr)
|
2026-02-19 20:44:04 +00:00
|
|
|
|
2026-02-19 13:44:16 +00:00
|
|
|
hello :: ByteString -> IO ()
|
|
|
|
|
hello s = useAsCString s $ Raw.hello . unsafeFromPtr
|
|
|
|
|
|
|
|
|
|
helloStruct :: T -> IO ()
|
|
|
|
|
helloStruct = Raw.hello_struct . convertT
|
|
|
|
|
|
|
|
|
|
helloShape :: Shape -> IO ()
|
|
|
|
|
helloShape = Raw.hello_shape . convertShape
|
2026-02-19 15:26:27 +00:00
|
|
|
|
2026-02-19 15:56:55 +00:00
|
|
|
add :: Int64 -> Int64 -> Int64
|
2026-02-19 15:47:55 +00:00
|
|
|
add = Raw.add
|
2026-02-19 20:44:04 +00:00
|
|
|
|
|
|
|
|
sumTree :: BTree Int64 -> IO Int64
|
|
|
|
|
sumTree = flip withBTree Raw.sum_tree
|