{-# LANGUAGE DoAndIfThenElse #-} module KikiD.Message where import Data.Serialize as Cereal import qualified Data.ByteString.Char8 as B import Data.Monoid import Text.Read import Data.Char (ord,chr) import Control.Monad import Data.Bytes.Serial as R import Data.Bytes.Put as Put import Data.Bytes.Get as Get import Codec.LineReady import Control.Monad.Loops import Data.Word data KikiDMessage = TODO deriving (Show,Read) instance Serialize KikiDMessage where put m = mapM_ (Cereal.putWord8 . fromIntegral . ord) "TO\nO" -- putByteString . B.pack $ show m ++ "\n" get = do t <- Cereal.getWord8 o <- Cereal.getWord8 d <- Cereal.getWord8 o <- Cereal.getWord8 let s = map (chr . fromIntegral) [t,o,d,o] if "TO\nO" == s then return TODO else fail ("Could not decode message: " ++ show s) instance Serial KikiDMessage where serialize m = Put.putByteString . toLineReady . Cereal.encode $ m deserialize = do xs <- unfoldM $ do flag <- Get.isEmpty if flag then return Nothing else do c <- fmap (chr . fromIntegral) Get.getWord8 if (c == '\n') then return Nothing else return (Just c) case (Cereal.decode . fromLineReady $ B.pack xs) of Left str -> fail str Right x -> return x