{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}

-- |
-- Module      : Language.Halide.Utils
-- Description : Utilities for writing FFI code
-- Copyright   : (c) Tom Westerhout, 2023
module Language.Halide.Utils
  ( peekCxxString
  , peekAndDeleteCxxString
  ) where

import Data.ByteString (packCString)
import Data.Text (Text)
import qualified Data.Text.Encoding as T
import Foreign.Ptr (Ptr)
import qualified Language.C.Inline.Unsafe as CU
import Language.Halide.Context
import Language.Halide.Type

importHalide

-- | Convert a pointer to @std::string@ into a string.
--
-- It properly handles unicode characters.
peekCxxString :: Ptr CxxString -> IO Text
peekCxxString :: Ptr CxxString -> IO Text
peekCxxString Ptr CxxString
p =
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Text
T.decodeUtf8 forall a b. (a -> b) -> a -> b
$
    CString -> IO ByteString
packCString
      forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< [CU.exp| char const* { $(const std::string* p)->c_str() } |]

-- | Call 'peekCxxString' and @delete@ the pointer.
peekAndDeleteCxxString :: Ptr CxxString -> IO Text
peekAndDeleteCxxString :: Ptr CxxString -> IO Text
peekAndDeleteCxxString Ptr CxxString
p = do
  Text
s <- Ptr CxxString -> IO Text
peekCxxString Ptr CxxString
p
  [CU.exp| void { delete $(const std::string* p) } |]
  forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
s