packages feed

haxr-th (empty) → 3000.0.0

raw patch · 3 files changed

+128/−0 lines, 3 filesdep +basedep +haxrdep +template-haskellbuild-type:Customsetup-changed

Dependencies added: base, haxr, template-haskell

Files

+ Network/XmlRpc/THDeriveXmlRpcType.hs view
@@ -0,0 +1,100 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Network.XmlRpc.THDeriveXmlRpcType+-- Copyright   :  (c) Bjorn Bringert 2003-2005+-- License     :  BSD-style+-- +-- Maintainer  :  bjorn@bringert.net+-- Stability   :  experimental+-- Portability :  non-portable (requires extensions and non-portable libraries)+--+-- Uses Template Haskell to automagically derive instances of 'XmlRpcType'+--+------------------------------------------------------------------------------++{-# LANGUAGE TemplateHaskell #-}+module Network.XmlRpc.THDeriveXmlRpcType (asXmlRpcStruct) where++import Control.Monad (replicateM, liftM)+import Data.List (genericLength)+import Data.Maybe (maybeToList)+import Language.Haskell.TH+import Network.XmlRpc.Internals hiding (Type)++-- | Creates an 'XmlRpcType' instance which handles a Haskell record+--   as an XmlRpc struct. Example:+-- @+-- data Person = Person { name :: String, age :: Int }+-- $(asXmlRpcStruct \'\'Person)+-- @+asXmlRpcStruct :: Name -> Q [Dec]+asXmlRpcStruct name = +    do+    info <- reify name+    dec <- case info of+		     TyConI d -> return d+		     _ -> fail $ show name ++ " is not a type constructor"+    mkInstance dec++mkInstance :: Dec -> Q [Dec]+mkInstance  (DataD _ n _ [RecC c fs] _) = +    do+    let ns = (map (\ (f,_,t) -> (unqual f, isMaybe t)) fs)+    tv <- mkToValue ns +    fv <- mkFromValue c ns+    gt <- mkGetType+    liftM (:[]) $ instanceD (cxt []) (appT (conT ''XmlRpcType)+				    (conT n)) +	      (map return $ concat [tv, fv, gt])++mkInstance _ = error "Can only derive XML-RPC type for simple record types"+++isMaybe :: Type -> Bool+isMaybe (AppT (ConT n) _) | n == ''Maybe = True+isMaybe _ = False+++unqual :: Name -> Name+unqual = mkName . reverse . takeWhile (`notElem` [':','.']) . reverse . show++mkToValue :: [(Name,Bool)] -> Q [Dec]+mkToValue fs = +    do+    p <- newName "p"+    simpleFun 'toValue [varP p] +		(appE (varE 'toValue)+			  (appE [| concat |] $ listE $ map (fieldToTuple p) fs))+++simpleFun :: Name -> [PatQ] -> ExpQ -> Q [Dec]+simpleFun n ps b = sequence [funD n [clause ps (normalB b) []]]++fieldToTuple :: Name -> (Name,Bool) -> ExpQ+fieldToTuple p (n,False) = listE [tupE [stringE (show n), +					 appE (varE 'toValue)+					 (appE (varE n) (varE p))+					]+				 ]+fieldToTuple p (n,True) = +    [| map (\v -> ($(stringE (show n)), toValue v)) $ maybeToList $(appE (varE n) (varE p)) |]++mkFromValue :: Name -> [(Name,Bool)] -> Q [Dec]+mkFromValue c fs = +    do+    names <- replicateM (length fs) (newName "x")+    v <- newName "v"+    t <- newName "t"+    simpleFun 'fromValue [varP v] $ +	       doE $ [bindS (varP t) (appE (varE 'fromValue) (varE v))] +++		      zipWith (mkGetField t) (map varP names) fs ++ +		      [noBindS $ appE [| return |] $ appsE (conE c:map varE names)]++mkGetField t p (f,False) = bindS p (appsE [varE 'getField, +					   stringE (show f), varE t])+mkGetField t p (f,True) = bindS p (appsE [varE 'getFieldMaybe, +					  stringE (show f), varE t])++mkGetType :: Q [Dec]+mkGetType = simpleFun 'getType [wildP] +	     (conE 'TStruct)
+ Setup.lhs view
@@ -0,0 +1,8 @@+#!/usr/bin/env runghc++> module Main where++> import Distribution.Simple++> main :: IO ()+> main = defaultMain
+ haxr-th.cabal view
@@ -0,0 +1,20 @@+Name: haxr-th+Version: 3000.0.0+Copyright: Bjorn Bringert, 2003-2006+Build-depends: base, haxr >= 3000.0.0, template-haskell+License: BSD4+License-file: ../LICENSE+Author: Bjorn Bringert <bjorn@bringert.net>+Maintainer: Bjorn Bringert <bjorn@bringert.net>+Homepage: http://www.haskell.org/haxr/+Synopsis: Automatic deriving of XML-RPC structs for Haskell records.+Description:+        HaXR is a library for writing XML-RPC +        client and server applications in Haskell.+        This package adds automatic deriving of+        XML-RPC structs for Haskell records,+        using Template Haskell.+Exposed-Modules:+        Network.XmlRpc.THDeriveXmlRpcType+Extensions: OverlappingInstances, TypeSynonymInstances, TemplateHaskell+GHC-options: -O2