module DoRequest(doRequest) where
import Prelude hiding (IOError)
import DialogueIO
import ContinuationIO(stdin,stdout,stderr)
import qualified System.IO as IO
import Directory(getDirectoryContents,removeFile)
import XCall
import System
import Time(getClockTime,toCalendarTime)
doRequest :: Request -> IO Response
doRequest req =
case req of
ReadFile filename -> rdCatch (readFile filename)
WriteFile filename contents -> wrCatch (writeFile filename contents)
WriteBinaryFile path contents -> wrCatch (writeBinaryFile path contents)
AppendFile filename contents -> wrCatch (appendFile filename contents)
ReadDirectory dir -> rdCatch' StrList (getDirectoryContents dir)
DeleteFile path -> otCatch (const Success) (removeFile path)
ReadChan channelname ->
if channelname==stdin
then rdCatch getContents
else return (Failure $ ReadError $
"ReadChan: unknown channel "++channelname)
AppendChan channelname contents
| channelname==stdout -> wr IO.stdout
| channelname==stderr -> wr IO.stderr
| otherwise -> return (Failure $ WriteError ("AppendChan: unknown channel "++channelname))
where wr chan = wrCatch (IO.hPutStr chan contents>>IO.hFlush chan)
XRequest _ -> doXCall req
XCommand _ -> doXCall req
GetAsyncInput -> doSCall req
SocketRequest _ -> doSCall req
Select _ -> doSCall req
ReadXdgFile {} -> doSCall req
WriteXdgFile {} -> doSCall req
GetTime -> otCatch ClockTime getClockTime
GetLocalTime -> otCatch CalendarTime (toCalendarTime =<< getClockTime)
Exit n -> exitWith (if n==0 then ExitSuccess else ExitFailure n)
_ -> return $ Failure $ OtherError
("doRequest: unimplemented request: "++show req)
rdCatch = rdCatch' Str
rdCatch' f io = catch (fmap f $ io) (return . Failure . ReadError . show)
wrCatch io =
catch (io >> return Success) (return . Failure . WriteError . show)
otCatch f io = catch (fmap f $ io) (return . Failure . OtherError . show)
-- Should be put elsewhere:
--instance Functor IO where map f io = io >>= (return . f)
writeBinaryFile path s = IO.withBinaryFile path IO.WriteMode (flip IO.hPutStr s)