chiasma-0.12.2.0: lib/Chiasma/Codec/Decode.hs
module Chiasma.Codec.Decode where
import qualified Data.Text as Text (null, unpack)
import Data.Text.Read (decimal)
import GHC.Generics (K1 (..), M1 (..), (:*:) (..))
import Prelude hiding (many)
import Text.Parsec.Char (digit, string)
import Text.ParserCombinators.Parsec (GenParser, many, parse)
import Chiasma.Data.DecodeError (DecodeFailure (BoolParsingFailure, IntParsingFailure, ParseFailure, TooFewFields))
import Chiasma.Data.TmuxId (
ClientId (ClientId),
PaneId (..),
SessionId (..),
WindowId (..),
panePrefix,
sessionPrefix,
windowPrefix,
)
class TmuxPrimDecode a where
primDecode :: Text -> Either DecodeFailure a
class TmuxDataDecode f where
dataDecode :: [Text] -> Either DecodeFailure ([Text], f a)
instance (TmuxDataDecode f, TmuxDataDecode g) => TmuxDataDecode (f :*: g) where
dataDecode fields = do
(rest, left) <- dataDecode fields
(rest1, right) <- dataDecode rest
pure (rest1, left :*: right)
instance TmuxDataDecode f => (TmuxDataDecode (M1 i c f)) where
dataDecode fields =
second M1 <$> dataDecode fields
instance TmuxPrimDecode a => (TmuxDataDecode (K1 c a)) where
dataDecode (a:as') = do
prim <- primDecode a
pure (as', K1 prim)
dataDecode [] = Left TooFewFields
readInt :: Text -> Text -> Either DecodeFailure Int
readInt text num =
first (const $ IntParsingFailure text) parsed
where
parsed = do
(num', rest) <- decimal num
if Text.null rest then Right num' else Left ""
instance TmuxPrimDecode Int where
primDecode field = readInt field field
instance TmuxPrimDecode Bool where
primDecode field =
convert =<< readInt field field
where
convert 0 =
Right False
convert 1 =
Right True
convert _ =
Left (BoolParsingFailure $ "got non-bool `" <> show field <> "`")
idParser :: Text -> GenParser Char st Text
idParser sym =
string (toString sym) *> (toText <$> many digit)
parseId :: (Int -> a) -> Text -> Text -> Either DecodeFailure a
parseId cons sym text = do
num <- first (ParseFailure "id") $ parse (idParser sym) "none" (Text.unpack text)
i <- readInt text num
pure (cons i)
instance TmuxPrimDecode ClientId where
primDecode = pure . ClientId
instance TmuxPrimDecode SessionId where
primDecode = parseId SessionId sessionPrefix
instance TmuxPrimDecode WindowId where
primDecode = parseId WindowId windowPrefix
instance TmuxPrimDecode PaneId where
primDecode = parseId PaneId panePrefix
instance TmuxPrimDecode [Char] where
primDecode = Right . toString
instance TmuxPrimDecode Text where
primDecode = Right