diff options
Diffstat (limited to 'src/Ssb/Aux.hs')
-rw-r--r-- | src/Ssb/Aux.hs | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/src/Ssb/Aux.hs b/src/Ssb/Aux.hs new file mode 100644 index 0000000..4be61b9 --- /dev/null +++ b/src/Ssb/Aux.hs @@ -0,0 +1,67 @@ +module Ssb.Aux where + +import Protolude + +import Data.Aeson as Aeson +import Data.ByteString.Lazy as BS (toStrict) +import Data.Default +import Data.Serialize as Serialize +import Data.Either.Combinators ( mapLeft + , mapRight + ) +import Control.Concurrent.STM +import System.IO ( hFlush + , hGetLine + , hSetBinaryMode + ) +import System.Process + + +-- | Convertible describes instances where types can be easily converted. +class Convertible a b where + convert :: a -> b + +-- | decodeJSON deserializes the JSON bytestring. +-- It is a reimplementation Aeson's eitherDecodeStrict which returns Text +-- instead of String. +decodeJSON :: (FromJSON a) => ByteString -> Either Text a +decodeJSON = mapLeft toS . Aeson.eitherDecodeStrict + +encodeJSON :: (ToJSON a) => a -> ByteString +encodeJSON = BS.toStrict . Aeson.encode + +encodeByteString :: Serialize.Serialize a => a -> ByteString +encodeByteString = Serialize.encode + +decodeByteString :: Serialize.Serialize a => ByteString -> Either Text a +decodeByteString a = mapLeft toS $ Serialize.decode a + +withErr :: Text -> Maybe a -> Either Text a +withErr = maybeToRight + +error :: Text -> Either Text a +error = Left + +maybeWord8 :: Int -> Either Text Word8 +maybeWord8 arg = if arg >= min && arg <= max + then return $ fromIntegral arg + else Left "out of bounds" + where + min = fromIntegral (minBound :: Word8) + max = fromIntegral (maxBound :: Word8) + +-- | TODO: kill command forked by forkCommand +command :: Text -> TMVar ByteString -> TMVar ByteString -> IO () +command cmd input output = do + (hIn, hOut, hErr, hProc) <- runInteractiveCommand (toS cmd) + hSetBinaryMode hIn False + hSetBinaryMode hOut False + hSetBinaryMode hErr False + let loop = do + v <- atomically $ takeTMVar input + hPutStr hIn (toS v :: [Char]) + hFlush hIn + v' <- hGetLine hOut + atomically $ putTMVar output (toS v') + loop + loop |