This commit is contained in:
George Thomas 2026-02-19 11:21:38 +00:00
parent e53fb108f4
commit 34ce6078ba
2 changed files with 30 additions and 4 deletions

View File

@ -3,6 +3,13 @@ set -euo pipefail
# TODO this is a complete vibe-coded hack, but the header patching at least is crucial # TODO this is a complete vibe-coded hack, but the header patching at least is crucial
# TODO fully-vibed hack
# we should do a few things quite differently anyway
# generated Haskell code shouldn't be checked in as it's not portable
# does the TH way of using `hs-bindgen` help here?
# I guess we shouldn't check in the generated C header either
# Generate Haskell FFI bindings from Rust source code. # Generate Haskell FFI bindings from Rust source code.
# #
# Pipeline: cargo build -> cbindgen -> patch header -> hs-bindgen # Pipeline: cargo build -> cbindgen -> patch header -> hs-bindgen
@ -90,7 +97,8 @@ pending_enum && /^typedef [A-Za-z0-9_]+ / {
} }
{ print } { print }
' "$HEADER" > "${HEADER}.tmp" && mv "${HEADER}.tmp" "$HEADER" ' "$HEADER" > "${HEADER}.tmp"
mv "${HEADER}.tmp" "$HEADER"
echo " Patched header at $HEADER" echo " Patched header at $HEADER"

View File

@ -1,14 +1,32 @@
module Main (main) where module Main (main) where
import Data.ByteString import Data.ByteString
import Data.Word
import Foreign.C import Foreign.C
import GarnetRs import GarnetRs
import GarnetRs.Safe import GarnetRs.Safe
import HsBindgen.Runtime.PtrConst import HsBindgen.Runtime.PtrConst
import Unsafe.Coerce
main :: IO () main :: IO ()
main = do main = do
useAsCString "Haskell" $ hello . unsafeFromPtr useAsCString "Haskell" $ hello . unsafeFromPtr
hello_struct T{a = CBool 1, b = 42} hello_struct $ convertT T'{a = True, b = 42}
hello_shape $ Shape (Shape_Tag 0) $ set_shape_body_circle $ Circle_Body 3.14 hello_struct $ convertT T'{a = False, b = 42}
hello_shape $ Shape (Shape_Tag 1) $ set_shape_body_rectangle $ Rectangle_Body 10.0 5.0 hello_shape $ convertShape $ Circle 3.14
hello_shape $ convertShape $ Rectangle 10.0 5.0
data T' = T'
{ a :: Bool
, b :: Word8
}
convertT T'{a, b} =
-- T{a = CBool $ unsafeCoerce @Bool @Word8 a, b}
T{a = CBool $ fromIntegral $ fromEnum a, b}
data Shape'
= Circle CDouble
| Rectangle CDouble CDouble
convertShape = \case
Circle r -> Shape (Shape_Tag 0) $ set_shape_body_circle $ Circle_Body r
Rectangle w h -> Shape (Shape_Tag 1) $ set_shape_body_rectangle $ Rectangle_Body w h