{-# LANGUAGE OverloadedStrings #-}
module Main (main) where
import Network.JsonRpc.Server
import Happstack.Server.SimpleHTTP( ServerPartT, simpleHTTP, nullConf
, askRq, rqBody, unBody, toResponse)
import Data.List (intercalate)
import Data.Maybe (fromMaybe)
import Control.Monad (when)
import Control.Monad.Trans (liftIO)
import Control.Monad.Error (throwError)
import Control.Monad.Reader (ReaderT, ask, runReaderT)
import Control.Concurrent.MVar (MVar, newMVar, readMVar, modifyMVar)
main :: IO ()
main = newMVar 0 >>= \count ->
simpleHTTP nullConf $ do
request <- askRq
body <- liftIO $ getBody request
result <- runReaderT (call methods body) count
let resultStr = fromMaybe "" result
return $ toResponse resultStr
where getBody r = unBody `fmap` readMVar (rqBody r)
type Server = ReaderT (MVar Integer) (ServerPartT IO)
methods :: Methods Server
methods = toMethods [printSequence, getCount, add]
printSequence, getCount, add :: Method Server
printSequence = toMethod "print" f params
where params = Required "string" :+:
Optional "count" 1 :+:
Optional "separator" ',' :+: ()
f :: String -> Int -> Char -> RpcResult Server ()
f str count sep = do
when (count < 0) $ throwError negativeCount
liftIO $ print $ intercalate [sep] $ replicate count str
negativeCount = rpcError (-32000) "negative count"
getCount = toMethod "get_count" f ()
where f :: RpcResult Server Integer
f = ask >>= \count -> liftIO $ modifyMVar count inc
where inc x = return (x + 1, x + 1)
add = toMethod "add" f (Required "x" :+: Required "y" :+: ())
where f :: Double -> Double -> RpcResult Server Double
f x y = liftIO $ return (x + y)