bustle-0.8.0: Bustle/GVariant.hs
{-
Bustle.GVariant: bindings for GVariant
Copyright © 2020 Will Thompson
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-}
{-# LANGUAGE ForeignFunctionInterface #-}
module Bustle.GVariant
(
-- * Types
GVariant
, TypeAnnotate(..)
-- * Constructors
, makeNewGVariant
, wrapNewGVariant
-- * Methods
, variantGetChild
, variantGetString
, variantPrint
)
where
import Foreign.ForeignPtr
import Foreign.Ptr
import Foreign.C
import System.Glib.UTFString
import Control.Monad (guard)
import Control.Monad.Trans (liftIO)
import Control.Monad.Trans.Maybe
data TypeAnnotate = NoAnnotations
| WithAnnotations
deriving
(Show, Ord, Eq, Enum)
newtype GVariant = GVariant { unGVariant :: ForeignPtr GVariant }
deriving (Eq, Ord, Show)
makeNewGVariant :: IO (Ptr GVariant)
-> IO GVariant
makeNewGVariant act = wrapNewGVariant (act >>= g_variant_ref)
wrapNewGVariant :: IO (Ptr GVariant)
-> IO GVariant
wrapNewGVariant act = do
vPtr <- act
v <- newForeignPtr g_variant_unref vPtr
return $ GVariant v
-- Foreign imports
foreign import ccall unsafe "g_variant_is_of_type"
g_variant_is_of_type :: Ptr a
-> CString
-> IO CInt
foreign import ccall unsafe "g_variant_n_children"
g_variant_n_children :: Ptr a
-> IO CSize
foreign import ccall unsafe "g_variant_get_child_value"
g_variant_get_child_value :: Ptr a
-> CSize
-> IO (Ptr a)
foreign import ccall unsafe "g_variant_get_string"
g_variant_get_string :: Ptr a
-> Ptr CSize
-> IO CString
foreign import ccall unsafe "g_variant_print"
g_variant_print :: Ptr a
-> CInt
-> IO CString
foreign import ccall unsafe "g_variant_ref"
g_variant_ref :: Ptr GVariant
-> IO (Ptr GVariant)
foreign import ccall unsafe "&g_variant_unref"
g_variant_unref :: FunPtr (Ptr GVariant -> IO ())
-- Bindings
variantNChildren :: GVariant
-> IO Word
variantNChildren v = withForeignPtr (unGVariant v) $ \vPtr -> do
fromIntegral <$> g_variant_n_children vPtr
variantGetChild :: GVariant
-> Word
-> IO (Maybe GVariant)
variantGetChild v i = withForeignPtr (unGVariant v) $ \vPtr -> runMaybeT $ do
n <- liftIO $ variantNChildren v
guard (i < n)
liftIO $ wrapNewGVariant $ g_variant_get_child_value vPtr (fromIntegral i)
variantGetString :: GVariant
-> IO (Maybe String)
variantGetString v = withForeignPtr (unGVariant v) $ \vPtr -> runMaybeT $ do
r <- liftIO $ withCString "s" $ g_variant_is_of_type vPtr
guard (r /= 0)
s <- liftIO $ g_variant_get_string vPtr nullPtr
liftIO $ peekUTFString s
variantPrint :: GVariant
-> TypeAnnotate
-> IO String
variantPrint v annotate = withForeignPtr (unGVariant v) $ \vPtr -> do
cstr <- g_variant_print vPtr (fromIntegral $ fromEnum annotate)
readUTFString cstr