clr-bindings-0.2.0: src/Clr/Bindings/Object.hs
{-# LANGUAGE TypeInType, TypeApplications, TypeSynonymInstances, MultiParamTypeClasses, FlexibleInstances, TypeFamilies, TypeOperators, ScopedTypeVariables, AllowAmbiguousTypes #-}
module Clr.Bindings.Object
( objectToString
, objectGetType
, downCast
) where
import Clr
import Clr.TypeString
import Clr.Marshal
import Clr.Host
import Clr.Host.BStr
import Clr.Host.GCHandle
import Clr.Bindings.DynImports
import Clr.Bindings.BStr
import Clr.Bindings.Object.Internal
import Data.Text as T
--
-- System.Object.ToString()
--
objectToString :: (t `Implements` T_object ~ 'True) => Object t -> IO T.Text
objectToString o = do
let o' = upCast o :: Object T_object
invokeI @T_ToString o' ()
--
-- System.Object.GetType()
--
objectGetType :: (t `Implements` T_object ~ 'True) => Object t -> IO (Object T_Type)
objectGetType o = do
let o' = upCast o :: Object T_object
invokeI @T_GetType o' ()
--
-- `downCast @typ o` is `Just o` casted to typ if possible, otherwise Nothing
--
downCast :: forall ts t t' .
( MakeT ts ~ t' -- Shorthand to long notation conversion
, TString t' -- And the result of the above can be turned into a runtime string
, t `Implements` T_object ~ 'True -- Supplied object must at least inherit from Object so we can call Object.GetType
, t' `Implements` t ~ 'True -- Ensure the desired cast is not something meaningless like cat -> dog at compile time
) => Object t -> IO (Maybe (Object t'))
downCast o = do
typ <- objectGetType o
typ' <- typeGetType (T.pack (tString @t'))
canDownCast <- typ' `typeIsAssignableFrom` typ
if canDownCast then
return $ Just $ unsafeDownCast o
else
return Nothing