module App.ReplProtocol (
Query(..), NotifySeq(..)
, Response(..)
, CmdResult(..), Result(..), Editor(..), File(..)
, FileType(..), file_type_extension
, empty_result, error_result, raw
, initialize
, query_cmd, query_save_file, query_completion
, notify
, query_cmd_simple
, seq_receive, seq_send
, format_result
, abbreviate_package_loads
) where
import qualified Control.DeepSeq as DeepSeq
import qualified Control.Exception as Exception
import qualified Data.ByteString as ByteString
import qualified Data.Text as Text
import qualified Network.Socket as Socket
import qualified System.IO as IO
import qualified System.IO.Error as IO.Error
import qualified System.Posix as Posix
import qualified Util.Lists as Lists
import qualified Util.Log as Log
import qualified Util.Network as Network
import qualified Util.PPrint as PPrint
import qualified Util.Serialize as Serialize
import Util.Serialize (get, get_tag, put, put_tag)
import qualified App.Config as Config
import Global
data Query =
QSaveFile
| QCommand !Text
| QCompletion !Text
| QNotify !NotifySeq
deriving (Query -> Query -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Query -> Query -> Bool
$c/= :: Query -> Query -> Bool
== :: Query -> Query -> Bool
$c== :: Query -> Query -> Bool
Eq, Int -> Query -> ShowS
[Query] -> ShowS
Query -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Query] -> ShowS
$cshowList :: [Query] -> ShowS
show :: Query -> String
$cshow :: Query -> String
showsPrec :: Int -> Query -> ShowS
$cshowsPrec :: Int -> Query -> ShowS
Show)
data NotifySeq =
NEditorOpened | NEditorClosed
deriving (NotifySeq -> NotifySeq -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: NotifySeq -> NotifySeq -> Bool
$c/= :: NotifySeq -> NotifySeq -> Bool
== :: NotifySeq -> NotifySeq -> Bool
$c== :: NotifySeq -> NotifySeq -> Bool
Eq, Int -> NotifySeq -> ShowS
[NotifySeq] -> ShowS
NotifySeq -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [NotifySeq] -> ShowS
$cshowList :: [NotifySeq] -> ShowS
show :: NotifySeq -> String
$cshow :: NotifySeq -> String
showsPrec :: Int -> NotifySeq -> ShowS
$cshowsPrec :: Int -> NotifySeq -> ShowS
Show)
data Response =
RSaveFile !(Maybe FilePath)
| RCommand !CmdResult
| RCompletion ![Text]
deriving (Response -> Response -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Response -> Response -> Bool
$c/= :: Response -> Response -> Bool
== :: Response -> Response -> Bool
$c== :: Response -> Response -> Bool
Eq, Int -> Response -> ShowS
[Response] -> ShowS
Response -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Response] -> ShowS
$cshowList :: [Response] -> ShowS
show :: Response -> String
$cshow :: Response -> String
showsPrec :: Int -> Response -> ShowS
$cshowsPrec :: Int -> Response -> ShowS
Show)
instance Pretty Query where
pretty :: Query -> Text
pretty = \case
Query
QSaveFile -> Text
"SaveFile"
QCommand Text
t -> Text
"Command: " forall a. Semigroup a => a -> a -> a
<> Text
t
QCompletion Text
t -> Text
"Completion: " forall a. Semigroup a => a -> a -> a
<> Text
t
QNotify NotifySeq
notify -> forall a. Show a => a -> Text
showt NotifySeq
notify
data CmdResult = CmdResult !Result ![Log.Msg]
deriving (CmdResult -> CmdResult -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CmdResult -> CmdResult -> Bool
$c/= :: CmdResult -> CmdResult -> Bool
== :: CmdResult -> CmdResult -> Bool
$c== :: CmdResult -> CmdResult -> Bool
Eq, Int -> CmdResult -> ShowS
[CmdResult] -> ShowS
CmdResult -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CmdResult] -> ShowS
$cshowList :: [CmdResult] -> ShowS
show :: CmdResult -> String
$cshow :: CmdResult -> String
showsPrec :: Int -> CmdResult -> ShowS
$cshowsPrec :: Int -> CmdResult -> ShowS
Show)
data Result =
Raw !Text
| Format !Text
| Edit !(NonEmpty Editor)
deriving (Result -> Result -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Result -> Result -> Bool
$c/= :: Result -> Result -> Bool
== :: Result -> Result -> Bool
$c== :: Result -> Result -> Bool
Eq, Int -> Result -> ShowS
[Result] -> ShowS
Result -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Result] -> ShowS
$cshowList :: [Result] -> ShowS
show :: Result -> String
$cshow :: Result -> String
showsPrec :: Int -> Result -> ShowS
$cshowsPrec :: Int -> Result -> ShowS
Show)
data Editor = Editor {
Editor -> File
_file :: !File
, Editor -> Int
_line_number :: !Int
, Editor -> Maybe Text
_on_save :: !(Maybe Text)
, Editor -> Maybe Text
_on_send :: !(Maybe Text)
} deriving (Editor -> Editor -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Editor -> Editor -> Bool
$c/= :: Editor -> Editor -> Bool
== :: Editor -> Editor -> Bool
$c== :: Editor -> Editor -> Bool
Eq, Int -> Editor -> ShowS
[Editor] -> ShowS
Editor -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Editor] -> ShowS
$cshowList :: [Editor] -> ShowS
show :: Editor -> String
$cshow :: Editor -> String
showsPrec :: Int -> Editor -> ShowS
$cshowsPrec :: Int -> Editor -> ShowS
Show)
data File =
FileName !FilePath
| Text !FileType !Text
deriving (File -> File -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: File -> File -> Bool
$c/= :: File -> File -> Bool
== :: File -> File -> Bool
$c== :: File -> File -> Bool
Eq, Int -> File -> ShowS
[File] -> ShowS
File -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [File] -> ShowS
$cshowList :: [File] -> ShowS
show :: File -> String
$cshow :: File -> String
showsPrec :: Int -> File -> ShowS
$cshowsPrec :: Int -> File -> ShowS
Show)
data FileType = NoType | Ky | TScore
deriving (FileType -> FileType -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FileType -> FileType -> Bool
$c/= :: FileType -> FileType -> Bool
== :: FileType -> FileType -> Bool
$c== :: FileType -> FileType -> Bool
Eq, Int -> FileType -> ShowS
[FileType] -> ShowS
FileType -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FileType] -> ShowS
$cshowList :: [FileType] -> ShowS
show :: FileType -> String
$cshow :: FileType -> String
showsPrec :: Int -> FileType -> ShowS
$cshowsPrec :: Int -> FileType -> ShowS
Show, FileType
forall a. a -> a -> Bounded a
maxBound :: FileType
$cmaxBound :: FileType
minBound :: FileType
$cminBound :: FileType
Bounded, Int -> FileType
FileType -> Int
FileType -> [FileType]
FileType -> FileType
FileType -> FileType -> [FileType]
FileType -> FileType -> FileType -> [FileType]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: FileType -> FileType -> FileType -> [FileType]
$cenumFromThenTo :: FileType -> FileType -> FileType -> [FileType]
enumFromTo :: FileType -> FileType -> [FileType]
$cenumFromTo :: FileType -> FileType -> [FileType]
enumFromThen :: FileType -> FileType -> [FileType]
$cenumFromThen :: FileType -> FileType -> [FileType]
enumFrom :: FileType -> [FileType]
$cenumFrom :: FileType -> [FileType]
fromEnum :: FileType -> Int
$cfromEnum :: FileType -> Int
toEnum :: Int -> FileType
$ctoEnum :: Int -> FileType
pred :: FileType -> FileType
$cpred :: FileType -> FileType
succ :: FileType -> FileType
$csucc :: FileType -> FileType
Enum)
file_type_extension :: FileType -> String
file_type_extension :: FileType -> String
file_type_extension = \case
FileType
NoType -> String
""
FileType
Ky -> String
".ky"
FileType
TScore -> String
".tscore"
empty_result :: Result
empty_result :: Result
empty_result = Text -> Result
Raw Text
""
error_result :: Text -> CmdResult
error_result :: Text -> CmdResult
error_result Text
msg = Result -> [Msg] -> CmdResult
CmdResult Result
empty_result [Stack => Priority -> Maybe Stack -> Text -> Msg
Log.msg Priority
Log.Error forall a. Maybe a
Nothing Text
msg]
raw :: Text -> CmdResult
raw :: Text -> CmdResult
raw Text
msg = Result -> [Msg] -> CmdResult
CmdResult (Text -> Result
Raw Text
msg) []
initialize :: IO a -> IO a
initialize :: forall a. IO a -> IO a
initialize IO a
app = forall a. IO a -> IO a
Socket.withSocketsDo forall a b. (a -> b) -> a -> b
$ do
Signal -> Handler -> Maybe SignalSet -> IO Handler
Posix.installHandler Signal
Posix.sigPIPE (IO () -> Handler
Posix.Catch IO ()
sigpipe) forall a. Maybe a
Nothing
IO a
app
where
sigpipe :: IO ()
sigpipe = Handle -> String -> IO ()
IO.hPutStrLn Handle
IO.stderr
String
"caught SIGPIPE, reader must have closed the socket"
query :: Network.Addr -> Query -> IO (Either Exception.IOException Response)
query :: Addr -> Query -> IO (Either IOException Response)
query Addr
addr Query
query = forall e a. Exception e => IO a -> IO (Either e a)
Exception.try forall a b. (a -> b) -> a -> b
$ forall a. Addr -> (Handle -> IO a) -> IO a
Network.withHandle Addr
addr forall a b. (a -> b) -> a -> b
$ \Handle
hdl -> do
Handle -> Query -> IO ()
repl_send Handle
hdl Query
query
Handle -> IO ()
IO.hFlush Handle
hdl
Handle -> IO Response
repl_receive Handle
hdl
notify :: Network.Addr -> NotifySeq -> IO (Either Exception.IOException ())
notify :: Addr -> NotifySeq -> IO (Either IOException ())
notify Addr
addr NotifySeq
notify = forall e a. Exception e => IO a -> IO (Either e a)
Exception.try forall a b. (a -> b) -> a -> b
$ forall a. Addr -> (Handle -> IO a) -> IO a
Network.withHandle Addr
addr forall a b. (a -> b) -> a -> b
$ \Handle
hdl -> do
Handle -> Query -> IO ()
repl_send Handle
hdl forall a b. (a -> b) -> a -> b
$ NotifySeq -> Query
QNotify NotifySeq
notify
Handle -> IO ()
IO.hFlush Handle
hdl
query_cmd :: Network.Addr -> Text -> IO CmdResult
query_cmd :: Addr -> Text -> IO CmdResult
query_cmd Addr
addr Text
cmd = Addr -> Query -> IO (Either IOException Response)
query Addr
addr (Text -> Query
QCommand Text
cmd) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
Right (RCommand CmdResult
result) -> CmdResult
result
Right Response
response -> Text -> CmdResult
raw forall a b. (a -> b) -> a -> b
$ Text
"unexpected response: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
showt Response
response
Left IOException
exc
| IOException -> Bool
IO.Error.isDoesNotExistError IOException
exc -> Text -> CmdResult
raw forall a b. (a -> b) -> a -> b
$
Text
"addr (" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
showt Addr
addr forall a. Semigroup a => a -> a -> a
<> Text
") threw ENOENT,\
\ this can happen if karya is not running, or it's stuck."
| Bool
otherwise -> Text -> CmdResult
raw forall a b. (a -> b) -> a -> b
$ Text
"exception: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
showt IOException
exc
query_cmd_simple :: Text -> IO Text
query_cmd_simple :: Text -> IO Text
query_cmd_simple Text
cmd =
CmdResult -> Text
format_result forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Addr -> Text -> IO CmdResult
query_cmd (String -> Addr
Network.Unix String
Config.repl_socket_name) Text
cmd
query_save_file :: Network.Addr -> IO (Maybe (Maybe FilePath))
query_save_file :: Addr -> IO (Maybe (Maybe String))
query_save_file Addr
addr = Addr -> Query -> IO (Either IOException Response)
query Addr
addr Query
QSaveFile forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Right (RSaveFile Maybe String
fname) -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just Maybe String
fname)
Left IOException
exc | IOException -> Bool
IO.Error.isDoesNotExistError IOException
exc -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
Either IOException Response
response -> do
forall (m :: * -> *). (Stack, LogMonad m) => Text -> m ()
Log.error forall a b. (a -> b) -> a -> b
$ Text
"unexpected response to QSaveFile: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
showt Either IOException Response
response
forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
query_completion :: Network.Addr -> Text -> IO [Text]
query_completion :: Addr -> Text -> IO [Text]
query_completion Addr
addr Text
prefix = Addr -> Query -> IO (Either IOException Response)
query Addr
addr (Text -> Query
QCompletion Text
prefix) forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Right (RCompletion [Text]
words) -> forall (m :: * -> *) a. Monad m => a -> m a
return [Text]
words
Left IOException
exc | IOException -> Bool
IO.Error.isDoesNotExistError IOException
exc -> forall (m :: * -> *) a. Monad m => a -> m a
return []
Either IOException Response
response -> do
forall (m :: * -> *). (Stack, LogMonad m) => Text -> m ()
Log.error forall a b. (a -> b) -> a -> b
$ Text
"unexpected response to QCompletion: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
showt Either IOException Response
response
forall (m :: * -> *) a. Monad m => a -> m a
return []
seq_receive :: IO.Handle -> IO Query
seq_receive :: Handle -> IO Query
seq_receive = forall a. Serialize a => Handle -> IO a
receive
seq_send :: IO.Handle -> Response -> IO ()
seq_send :: Handle -> Response -> IO ()
seq_send = forall a. Serialize a => Handle -> a -> IO ()
send
repl_send :: IO.Handle -> Query -> IO ()
repl_send :: Handle -> Query -> IO ()
repl_send = forall a. Serialize a => Handle -> a -> IO ()
send
repl_receive :: IO.Handle -> IO Response
repl_receive :: Handle -> IO Response
repl_receive = forall a. Serialize a => Handle -> IO a
receive
send :: Serialize.Serialize a => IO.Handle -> a -> IO ()
send :: forall a. Serialize a => Handle -> a -> IO ()
send Handle
hdl a
msg = do
Handle -> ByteString -> IO ()
ByteString.hPut Handle
hdl (forall a. Serialize a => a -> ByteString
Serialize.encode (ByteString -> Int
ByteString.length ByteString
bytes))
Handle -> ByteString -> IO ()
ByteString.hPut Handle
hdl ByteString
bytes
where bytes :: ByteString
bytes = forall a. Serialize a => a -> ByteString
Serialize.encode a
msg
receive :: Serialize.Serialize a => IO.Handle -> IO a
receive :: forall a. Serialize a => Handle -> IO a
receive Handle
hdl = do
let int_bytes :: Int
int_bytes = ByteString -> Int
ByteString.length (forall a. Serialize a => a -> ByteString
Serialize.encode (Int
0 :: Int))
ByteString
size <- Handle -> Int -> IO ByteString
ByteString.hGet Handle
hdl Int
int_bytes
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ByteString
size forall a. Eq a => a -> a -> Bool
== ByteString
"") forall a b. (a -> b) -> a -> b
$
forall e a. Exception e => e -> IO a
Exception.throwIO forall a b. (a -> b) -> a -> b
$ IOErrorType
-> String -> Maybe Handle -> Maybe String -> IOException
IO.Error.mkIOError IOErrorType
IO.Error.doesNotExistErrorType
String
"client closed handle" forall a. Maybe a
Nothing forall a. Maybe a
Nothing
Int
size <- forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall (m :: * -> *) a. (Stack, MonadIO m) => Text -> m a
errorIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
txt) forall (m :: * -> *) a. Monad m => a -> m a
return (forall a. Serialize a => ByteString -> Either String a
Serialize.decode ByteString
size)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (forall (m :: * -> *) a. (Stack, MonadIO m) => Text -> m a
errorIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
txt) forall (m :: * -> *) a. Monad m => a -> m a
return forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Serialize a => ByteString -> Either String a
Serialize.decode
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Handle -> Int -> IO ByteString
ByteString.hGet Handle
hdl Int
size
format_result :: CmdResult -> Text
format_result :: CmdResult -> Text
format_result (CmdResult Result
response [Msg]
logs_) =
Text -> Text
Text.stripEnd forall a b. (a -> b) -> a -> b
$ [Text] -> Text
Text.unlines forall a b. (a -> b) -> a -> b
$
(if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Msg]
logs then [] else Text
"Logs:" forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map forall a. Pretty a => a -> Text
pretty [Msg]
logs forall a. [a] -> [a] -> [a]
++ [Text
""])
forall a. [a] -> [a] -> [a]
++ [Result -> Text
format Result
response]
where logs :: [Msg]
logs = [Msg] -> [Msg]
abbreviate_package_loads [Msg]
logs_
format :: Result -> Text
format :: Result -> Text
format (Raw Text
val) = Text
val
format (Format Text
val) = String -> Text
txt forall a b. (a -> b) -> a -> b
$ ShowS
PPrint.format_str forall a b. (a -> b) -> a -> b
$ Text -> String
untxt Text
val
format (Edit NonEmpty Editor
editors) = Text
"Edit: " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
showt (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Editor -> File
_file NonEmpty Editor
editors)
abbreviate_package_loads :: [Log.Msg] -> [Log.Msg]
abbreviate_package_loads :: [Msg] -> [Msg]
abbreviate_package_loads [Msg]
logs = [Msg]
loaded forall a. [a] -> [a] -> [a]
++ forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. Msg -> Bool
package_log) [Msg]
logs
where
loaded :: [Msg]
loaded =
[ Stack => Priority -> Maybe Stack -> Text -> Msg
Log.msg Priority
Log.Notice forall a. Maybe a
Nothing forall a b. (a -> b) -> a -> b
$
Text
"Loaded " forall a. Semigroup a => a -> a -> a
<> String -> Text
Text.pack (forall a. Show a => a -> String
show Int
packages) forall a. Semigroup a => a -> a -> a
<> Text
" packages"
| Int
packages forall a. Ord a => a -> a -> Bool
> Int
0
]
packages :: Int
packages =
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Int
Lists.count ((Text
"Loading package" `Text.isPrefixOf`) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Msg -> Text
Log.msg_text) [Msg]
logs
package_log :: Msg -> Bool
package_log Msg
log = forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Text -> Text -> Bool
`Text.isPrefixOf` Msg -> Text
Log.msg_text Msg
log)
[Text
"Loading package", Text
"linking ...", Text
"done."]
instance Serialize.Serialize Query where
put :: Putter Query
put Query
QSaveFile = Word8 -> Put
put_tag Word8
0
put (QCommand Text
a) = Word8 -> Put
put_tag Word8
1 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put Text
a
put (QCompletion Text
a) = Word8 -> Put
put_tag Word8
2 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put Text
a
put (QNotify NotifySeq
a) = Word8 -> Put
put_tag Word8
3 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put NotifySeq
a
get :: Get Query
get = Get Word8
get_tag forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Word8
0 -> forall (m :: * -> *) a. Monad m => a -> m a
return Query
QSaveFile
Word8
1 -> Text -> Query
QCommand forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get
Word8
2 -> Text -> Query
QCompletion forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get
Word8
3 -> NotifySeq -> Query
QNotify forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get
Word8
tag -> forall a. String -> Word8 -> Get a
Serialize.bad_tag String
"Query" Word8
tag
instance Serialize.Serialize NotifySeq where
put :: Putter NotifySeq
put = \case
NotifySeq
NEditorOpened -> Word8 -> Put
put_tag Word8
0
NotifySeq
NEditorClosed -> Word8 -> Put
put_tag Word8
1
get :: Get NotifySeq
get = Get Word8
get_tag forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Word8
0 -> forall (m :: * -> *) a. Monad m => a -> m a
return NotifySeq
NEditorOpened
Word8
1 -> forall (m :: * -> *) a. Monad m => a -> m a
return NotifySeq
NEditorClosed
Word8
tag -> forall a. String -> Word8 -> Get a
Serialize.bad_tag String
"NotifySeq" Word8
tag
instance Serialize.Serialize Response where
put :: Putter Response
put (RSaveFile Maybe String
a) = Word8 -> Put
put_tag Word8
0 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put Maybe String
a
put (RCommand CmdResult
a) = Word8 -> Put
put_tag Word8
1 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put CmdResult
a
put (RCompletion [Text]
a) = Word8 -> Put
put_tag Word8
2 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put [Text]
a
get :: Get Response
get = Get Word8
get_tag forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Word8
0 -> Maybe String -> Response
RSaveFile forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get
Word8
1 -> CmdResult -> Response
RCommand forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get
Word8
2 -> [Text] -> Response
RCompletion forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get
Word8
tag -> forall a. String -> Word8 -> Get a
Serialize.bad_tag String
"Response" Word8
tag
instance Serialize.Serialize CmdResult where
put :: Putter CmdResult
put (CmdResult Result
a [Msg]
b) = forall a. Serialize a => Putter a
put Result
a forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put [Msg]
b
get :: Get CmdResult
get = Result -> [Msg] -> CmdResult
CmdResult forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Serialize a => Get a
get
instance Serialize.Serialize Result where
put :: Putter Result
put (Raw Text
a) = Word8 -> Put
put_tag Word8
0 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put Text
a
put (Format Text
a) = Word8 -> Put
put_tag Word8
1 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put Text
a
put (Edit NonEmpty Editor
a) = Word8 -> Put
put_tag Word8
2 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put NonEmpty Editor
a
get :: Get Result
get = Get Word8
get_tag forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Word8
0 -> Text -> Result
Raw forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get
Word8
1 -> Text -> Result
Format forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get
Word8
2 -> NonEmpty Editor -> Result
Edit forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get
Word8
tag -> forall a. String -> Word8 -> Get a
Serialize.bad_tag String
"Result" Word8
tag
instance Serialize.Serialize Editor where
put :: Putter Editor
put (Editor File
a Int
b Maybe Text
c Maybe Text
d) = forall a. Serialize a => Putter a
put File
a forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put Int
b forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put Maybe Text
c forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put Maybe Text
d
get :: Get Editor
get = File -> Int -> Maybe Text -> Maybe Text -> Editor
Editor forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Serialize a => Get a
get forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Serialize a => Get a
get forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Serialize a => Get a
get
instance Serialize.Serialize File where
put :: Putter File
put (FileName String
a) = Word8 -> Put
put_tag Word8
0 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put String
a
put (Text FileType
a Text
b) = Word8 -> Put
put_tag Word8
1 forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put FileType
a forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Serialize a => Putter a
put Text
b
get :: Get File
get = Get Word8
get_tag forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Word8
0 -> String -> File
FileName forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get
Word8
1 -> FileType -> Text -> File
Text forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Serialize a => Get a
get forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Serialize a => Get a
get
Word8
tag -> forall a. String -> Word8 -> Get a
Serialize.bad_tag String
"File" Word8
tag
instance Serialize.Serialize FileType where
put :: Putter FileType
put = forall a. Enum a => a -> Put
Serialize.put_enum_unsafe
get :: Get FileType
get = forall a. (Bounded a, Enum a) => Get a
Serialize.get_enum_unsafe
instance DeepSeq.NFData CmdResult where
rnf :: CmdResult -> ()
rnf (CmdResult Result
a [Msg]
b) = Result
a seq :: forall a b. a -> b -> b
`seq` [Msg]
b seq :: forall a b. a -> b -> b
`seq` ()