module HsDev.Server.Message.Lisp (
Msg,
isLisp, msg,
jsonMsg, lispMsg,
decodeMsg, encodeMsg
) where
import Control.Applicative
import Control.Lens
import Control.Monad
import Data.Aeson
import Data.Maybe
import Data.ByteString.Lazy.Char8 (ByteString)
import Data.Lisp
type Msg a = (Bool, a)
isLisp :: Lens' (Msg a) Bool
isLisp = _1
msg :: Lens (Msg a) (Msg b) a b
msg = _2
jsonMsg :: a -> Msg a
jsonMsg = (,) False
lispMsg :: a -> Msg a
lispMsg = (,) True
decodeMsg :: FromJSON a => ByteString -> Either (Msg String) (Msg a)
decodeMsg bstr = over _Left decodeType' decodeMsg' where
decodeType'
| isLisp' = lispMsg
| otherwise = jsonMsg
decodeMsg' = (lispMsg <$> decodeLisp bstr) <|> (jsonMsg <$> eitherDecode bstr)
isLisp' = fromMaybe False $ mplus (try' eitherDecode False) (try' decodeLisp True)
try' :: (ByteString -> Either String Value) -> Bool -> Maybe Bool
try' f l = either (const Nothing) (const $ Just l) $ f bstr
encodeMsg :: ToJSON a => Msg a -> ByteString
encodeMsg m
| view isLisp m = encodeLisp $ view msg m
| otherwise = encode $ view msg m