packages feed

dbus-th 0.1.2.0 → 0.1.3.0

raw patch · 4 files changed

+199/−199 lines, 4 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- DBus.TH: (:->) :: Name -> Signature -> Signature
- DBus.TH: (=::) :: String -> Signature -> Function
- DBus.TH: Function :: String -> String -> Signature -> Function
- DBus.TH: Return :: Name -> Signature
- DBus.TH: [fnDBusName] :: Function -> String
- DBus.TH: [fnName] :: Function -> String
- DBus.TH: [fnSignature] :: Function -> Signature
- DBus.TH: as :: Function -> String -> Function
- DBus.TH: connectSession :: IO Client
- DBus.TH: connectSystem :: IO Client
- DBus.TH: data BusName :: *
- DBus.TH: data Client :: *
- DBus.TH: data Function
- DBus.TH: data InterfaceName :: *
- DBus.TH: data MemberName :: *
- DBus.TH: data ObjectPath :: *
- DBus.TH: data Signature
- DBus.TH: data Variant :: *
- DBus.TH: function :: String -> String -> String -> Maybe String -> Function -> Q [Dec]
- DBus.TH: function' :: String -> Maybe String -> String -> Maybe String -> Function -> Q [Dec]
- DBus.TH: instance Data.Data.Data DBus.TH.Function
- DBus.TH: instance Data.Data.Data DBus.TH.Signature
- DBus.TH: instance GHC.Classes.Eq DBus.TH.Function
- DBus.TH: instance GHC.Classes.Eq DBus.TH.Signature
- DBus.TH: instance GHC.Show.Show DBus.TH.Function
- DBus.TH: instance GHC.Show.Show DBus.TH.Signature
- DBus.TH: interface :: String -> String -> String -> Maybe String -> [Function] -> Q [Dec]
- DBus.TH: interface' :: String -> Maybe String -> String -> Maybe String -> [Function] -> Q [Dec]
- DBus.TH: signatureResult :: Signature -> Name
+ DBus.TH.EDSL: (:->) :: Name -> Signature -> Signature
+ DBus.TH.EDSL: (=::) :: String -> Signature -> Function
+ DBus.TH.EDSL: Function :: String -> String -> Signature -> Function
+ DBus.TH.EDSL: Return :: Name -> Signature
+ DBus.TH.EDSL: [fnDBusName] :: Function -> String
+ DBus.TH.EDSL: [fnName] :: Function -> String
+ DBus.TH.EDSL: [fnSignature] :: Function -> Signature
+ DBus.TH.EDSL: as :: Function -> String -> Function
+ DBus.TH.EDSL: connectSession :: IO Client
+ DBus.TH.EDSL: connectSystem :: IO Client
+ DBus.TH.EDSL: data BusName :: *
+ DBus.TH.EDSL: data Client :: *
+ DBus.TH.EDSL: data Function
+ DBus.TH.EDSL: data InterfaceName :: *
+ DBus.TH.EDSL: data MemberName :: *
+ DBus.TH.EDSL: data ObjectPath :: *
+ DBus.TH.EDSL: data Signature
+ DBus.TH.EDSL: data Variant :: *
+ DBus.TH.EDSL: function :: String -> String -> String -> Maybe String -> Function -> Q [Dec]
+ DBus.TH.EDSL: function' :: String -> Maybe String -> String -> Maybe String -> Function -> Q [Dec]
+ DBus.TH.EDSL: infixl 4 `as`
+ DBus.TH.EDSL: infixr 5 =::
+ DBus.TH.EDSL: instance Data.Data.Data DBus.TH.EDSL.Function
+ DBus.TH.EDSL: instance Data.Data.Data DBus.TH.EDSL.Signature
+ DBus.TH.EDSL: instance GHC.Classes.Eq DBus.TH.EDSL.Function
+ DBus.TH.EDSL: instance GHC.Classes.Eq DBus.TH.EDSL.Signature
+ DBus.TH.EDSL: instance GHC.Show.Show DBus.TH.EDSL.Function
+ DBus.TH.EDSL: instance GHC.Show.Show DBus.TH.EDSL.Signature
+ DBus.TH.EDSL: interface :: String -> String -> String -> Maybe String -> [Function] -> Q [Dec]
+ DBus.TH.EDSL: interface' :: String -> Maybe String -> String -> Maybe String -> [Function] -> Q [Dec]
+ DBus.TH.EDSL: signatureResult :: Signature -> Name

Files

− DBus/TH.hs
@@ -1,196 +0,0 @@-{-# LANGUAGE TemplateHaskell, TypeOperators, DeriveDataTypeable #-}--module DBus.TH-  (module Data.Int,-   module Data.Word,-   Client, BusName,-   ObjectPath, InterfaceName,-   MemberName, Variant,-   connectSession, connectSystem,-   Signature (..),-   signatureResult,-   Function (..),-   (=::), as,-   function, interface,-   function', interface'-  ) where--import Control.Monad-import Data.Int-import Data.Word-import Language.Haskell.TH-import qualified Data.Text as Text-import Data.Char-import Data.List-import Data.Generics-import DBus hiding (Type, Signature)-import DBus.Client hiding (Type, Signature)---- | Function signature-data Signature = Return Name-               | Name :-> Signature-  deriving (Eq, Show, Data, Typeable)--infixr 6 :->---- | Function with DBus name and Haskell name-data Function = Function {-    fnName      :: String    -- ^ Function name to use in Haskell-  , fnDBusName  :: String    -- ^ Function name to use in DBus-  , fnSignature :: Signature -- ^ Function signature-    }-  deriving (Eq, Show, Data, Typeable)---- | Create a Function from it's name and Signature.--- Sets fnDBusName == fnName.-(=::) :: String -> Signature -> Function-name =:: sig = Function name name sig--infixr 5 =::---- | Set specific Haskell name for Function.-as :: Function -> String -> Function-fn `as` name = fn {fnName = name}--infixl 4 `as`--nArgs :: Signature -> Int-nArgs (Return _) = 0-nArgs (_ :-> s)  = 1 + nArgs s--firstLower :: String -> String-firstLower [] = []-firstLower (x:xs) = toLower x: xs---- | Return type name for signature-signatureResult :: Signature -> Name-signatureResult (Return name) = name-signatureResult (_ :-> sig) = signatureResult sig---- | Generate bindings for methods in specific DBus interface.--- If second argument is (Just prefix), then prefix will be--- added to the beginning of all DBus names and removed from all--- Haskell names.-interface :: String       -- ^ Bus name-          -> String       -- ^ Object name-          -> String       -- ^ Interface name-          -> Maybe String -- ^ Prefix-          -> [Function]   -- ^ List of functions-          -> Q [Dec]-interface busName objectName ifaceName mbPrefix fns =-    interface' busName (Just objectName) ifaceName mbPrefix fns---- | Generate bindings for methods in specific DBus interface.--- If second argument is (Just prefix), then prefix will be--- added to the beginning of all DBus names and removed from all--- Haskell names.-interface' :: String      -- ^ Bus name-          -> Maybe String -- ^ Just name - use fixed object name; Nothing - object name will be 2nd argument of generated functions-          -> String       -- ^ Interface name-          -> Maybe String -- ^ Prefix-          -> [Function]   -- ^ List of functions-          -> Q [Dec]-interface' busName mbObjectName ifaceName mbPrefix fns =-    concat `fmap` mapM (function' busName mbObjectName ifaceName mbPrefix) fns---- | Generate binding for one method in specific DBus interface.--- If second argument is (Just prefix), then prefix will be--- added to the beginning of all DBus names and removed from all--- Haskell names.-function :: String       -- ^ Bus name-          -> String       -- ^ Object name-          -> String       -- ^ Interface name-          -> Maybe String -- ^ Prefix-          -> Function   -- ^ Function-          -> Q [Dec]-function busName objectName ifaceName mbPrefix fn =-    function' busName (Just objectName) ifaceName mbPrefix fn---- | Generate binding for one method in specific DBus interface.--- If second argument is (Just prefix), then prefix will be--- added to the beginning of all DBus names and removed from all--- Haskell names.-function' :: String       -- ^ Bus name-          -> Maybe String -- ^ Just name - use fixed object name; Nothing - object name will be 2nd argument of generated function-          -> String       -- ^ Interface name-          -> Maybe String -- ^ Prefix-          -> Function     -- ^ Function-          -> Q [Dec]-function' busName mbObjectName ifaceName mbPrefix (Function name dbusName sig) =-    let name'     = strip name-        dbusName' = addPrefix dbusName-    in sequence [generateSignature name' sig,-                 generateImplementation name' dbusName' sig]-  where-    addPrefix :: String -> String-    addPrefix s =-      case mbPrefix of-        Nothing     -> s-        Just prefix -> prefix ++ s--    strip :: String -> String-    strip s =-      case mbPrefix of-        Nothing     -> s-        Just prefix -> if prefix `isPrefixOf` s-                         then drop (length prefix) s-                         else s--    generateSignature :: String -> Signature -> Q Dec-    generateSignature name sig = do-        dbt <- dbusType (transformType sig)-        return $ SigD (mkName $ firstLower name) dbt--    dbusType :: Type -> Q Type-    dbusType t =-      case mbObjectName of-        Just _ -> [t| Client -> $(return t) |]-        Nothing -> [t| Client -> String -> $(return t) |]--    transformType :: Signature -> Type-    transformType (Return t) =-      if t == ''()-        then AppT (ConT ''IO) (ConT ''())-        else AppT (ConT ''IO) (AppT (ConT ''Maybe) (ConT t))-    transformType (t :-> s)  = AppT (AppT ArrowT (ConT t)) (transformType s)--    generateImplementation :: String -> String -> Signature -> Q Dec-    generateImplementation name dbusName sig = do-        let bus  = mkName "bus"-        objectName <- newName "object"-        args <- replicateM (nArgs sig) (newName "x")-        body <- generateBody dbusName objectName sig args-        let varArgs = case mbObjectName of-                        Just _ -> VarP bus : map VarP args-                        Nothing -> VarP bus : VarP objectName : map VarP args-        return $ FunD (mkName $ firstLower name) [Clause varArgs (NormalB body) []]--    generateBody :: String -> Name -> Signature -> [Name] -> Q Exp-    generateBody name objectName sig names = do-        [| do-           let baseMethod = methodCall (objectPath_ $(case mbObjectName of-                                                        Just oname -> litE (StringL oname)-                                                        Nothing -> varE objectName-                                                      ))-                                       (interfaceName_ ifaceName)-                                       (memberName_ name)-               method = baseMethod {-                          methodCallDestination = Just (busName_ busName),-                          methodCallBody = $(variant names)-                        }-                      -           res <- call_ $(varE $ mkName "bus") method-           $(if signatureResult sig /= ''() -             then [| return $ fromVariant (methodReturnBody res !! 0) |]-             else [| return () |]-            )-          |]--    variant :: [Name] -> Q Exp-    variant names = do-      exs <- mapM variant1 names-      return $ ListE exs--    variant1 :: Name -> Q Exp-    variant1 name = [| toVariant $(varE name) |]-
+ DBus/TH/EDSL.hs view
@@ -0,0 +1,196 @@+{-# LANGUAGE TemplateHaskell, TypeOperators, DeriveDataTypeable #-}++module DBus.TH.EDSL+  (module Data.Int,+   module Data.Word,+   Client, BusName,+   ObjectPath, InterfaceName,+   MemberName, Variant,+   connectSession, connectSystem,+   Signature (..),+   signatureResult,+   Function (..),+   (=::), as,+   function, interface,+   function', interface'+  ) where++import Control.Monad+import Data.Int+import Data.Word+import Language.Haskell.TH+import qualified Data.Text as Text+import Data.Char+import Data.List+import Data.Generics+import DBus hiding (Type, Signature)+import DBus.Client hiding (Type, Signature)++-- | Function signature+data Signature = Return Name+               | Name :-> Signature+  deriving (Eq, Show, Data, Typeable)++infixr 6 :->++-- | Function with DBus name and Haskell name+data Function = Function {+    fnName      :: String    -- ^ Function name to use in Haskell+  , fnDBusName  :: String    -- ^ Function name to use in DBus+  , fnSignature :: Signature -- ^ Function signature+    }+  deriving (Eq, Show, Data, Typeable)++-- | Create a Function from it's name and Signature.+-- Sets fnDBusName == fnName.+(=::) :: String -> Signature -> Function+name =:: sig = Function name name sig++infixr 5 =::++-- | Set specific Haskell name for Function.+as :: Function -> String -> Function+fn `as` name = fn {fnName = name}++infixl 4 `as`++nArgs :: Signature -> Int+nArgs (Return _) = 0+nArgs (_ :-> s)  = 1 + nArgs s++firstLower :: String -> String+firstLower [] = []+firstLower (x:xs) = toLower x: xs++-- | Return type name for signature+signatureResult :: Signature -> Name+signatureResult (Return name) = name+signatureResult (_ :-> sig) = signatureResult sig++-- | Generate bindings for methods in specific DBus interface.+-- If second argument is (Just prefix), then prefix will be+-- added to the beginning of all DBus names and removed from all+-- Haskell names.+interface :: String       -- ^ Bus name+          -> String       -- ^ Object name+          -> String       -- ^ Interface name+          -> Maybe String -- ^ Prefix+          -> [Function]   -- ^ List of functions+          -> Q [Dec]+interface busName objectName ifaceName mbPrefix fns =+    interface' busName (Just objectName) ifaceName mbPrefix fns++-- | Generate bindings for methods in specific DBus interface.+-- If second argument is (Just prefix), then prefix will be+-- added to the beginning of all DBus names and removed from all+-- Haskell names.+interface' :: String      -- ^ Bus name+          -> Maybe String -- ^ Just name - use fixed object name; Nothing - object name will be 2nd argument of generated functions+          -> String       -- ^ Interface name+          -> Maybe String -- ^ Prefix+          -> [Function]   -- ^ List of functions+          -> Q [Dec]+interface' busName mbObjectName ifaceName mbPrefix fns =+    concat `fmap` mapM (function' busName mbObjectName ifaceName mbPrefix) fns++-- | Generate binding for one method in specific DBus interface.+-- If second argument is (Just prefix), then prefix will be+-- added to the beginning of all DBus names and removed from all+-- Haskell names.+function :: String       -- ^ Bus name+          -> String       -- ^ Object name+          -> String       -- ^ Interface name+          -> Maybe String -- ^ Prefix+          -> Function   -- ^ Function+          -> Q [Dec]+function busName objectName ifaceName mbPrefix fn =+    function' busName (Just objectName) ifaceName mbPrefix fn++-- | Generate binding for one method in specific DBus interface.+-- If second argument is (Just prefix), then prefix will be+-- added to the beginning of all DBus names and removed from all+-- Haskell names.+function' :: String       -- ^ Bus name+          -> Maybe String -- ^ Just name - use fixed object name; Nothing - object name will be 2nd argument of generated function+          -> String       -- ^ Interface name+          -> Maybe String -- ^ Prefix+          -> Function     -- ^ Function+          -> Q [Dec]+function' busName mbObjectName ifaceName mbPrefix (Function name dbusName sig) =+    let name'     = strip name+        dbusName' = addPrefix dbusName+    in sequence [generateSignature name' sig,+                 generateImplementation name' dbusName' sig]+  where+    addPrefix :: String -> String+    addPrefix s =+      case mbPrefix of+        Nothing     -> s+        Just prefix -> prefix ++ s++    strip :: String -> String+    strip s =+      case mbPrefix of+        Nothing     -> s+        Just prefix -> if prefix `isPrefixOf` s+                         then drop (length prefix) s+                         else s++    generateSignature :: String -> Signature -> Q Dec+    generateSignature name sig = do+        dbt <- dbusType (transformType sig)+        return $ SigD (mkName $ firstLower name) dbt++    dbusType :: Type -> Q Type+    dbusType t =+      case mbObjectName of+        Just _ -> [t| Client -> $(return t) |]+        Nothing -> [t| Client -> String -> $(return t) |]++    transformType :: Signature -> Type+    transformType (Return t) =+      if t == ''()+        then AppT (ConT ''IO) (ConT ''())+        else AppT (ConT ''IO) (AppT (ConT ''Maybe) (ConT t))+    transformType (t :-> s)  = AppT (AppT ArrowT (ConT t)) (transformType s)++    generateImplementation :: String -> String -> Signature -> Q Dec+    generateImplementation name dbusName sig = do+        let bus  = mkName "bus"+        objectName <- newName "object"+        args <- replicateM (nArgs sig) (newName "x")+        body <- generateBody dbusName objectName sig args+        let varArgs = case mbObjectName of+                        Just _ -> VarP bus : map VarP args+                        Nothing -> VarP bus : VarP objectName : map VarP args+        return $ FunD (mkName $ firstLower name) [Clause varArgs (NormalB body) []]++    generateBody :: String -> Name -> Signature -> [Name] -> Q Exp+    generateBody name objectName sig names = do+        [| do+           let baseMethod = methodCall (objectPath_ $(case mbObjectName of+                                                        Just oname -> litE (StringL oname)+                                                        Nothing -> varE objectName+                                                      ))+                                       (interfaceName_ ifaceName)+                                       (memberName_ name)+               method = baseMethod {+                          methodCallDestination = Just (busName_ busName),+                          methodCallBody = $(variant names)+                        }+                      +           res <- call_ $(varE $ mkName "bus") method+           $(if signatureResult sig /= ''() +             then [| return $ fromVariant (methodReturnBody res !! 0) |]+             else [| return () |]+            )+          |]++    variant :: [Name] -> Q Exp+    variant names = do+      exs <- mapM variant1 names+      return $ ListE exs++    variant1 :: Name -> Q Exp+    variant1 name = [| toVariant $(varE name) |]+
Test.hs view
@@ -2,7 +2,7 @@  import Control.Monad import qualified Data.Map as M-import DBus.TH+import DBus.TH.EDSL import System.Environment  type Ints = [Int32]
dbus-th.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                dbus-th-version:             0.1.2.0+version:             0.1.3.0 synopsis:            TemplateHaskell generator of DBus bindings description:         This package provides functions to easily generate bindings for                      DBus functions. See Test.hs for examples.@@ -17,7 +17,7 @@ extra-source-files:  Test.hs  library-  exposed-modules:     DBus.TH+  exposed-modules:     DBus.TH.EDSL   -- other-modules:          build-depends:       base > 4 && < 5, containers >= 0.4,                        syb >= 0.3.6,