{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeInType #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TupleSections #-}
{-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-}
module Language.LSP.Types.Message where
import Language.LSP.Types.Cancellation
import Language.LSP.Types.CodeAction
import Language.LSP.Types.CodeLens
import Language.LSP.Types.Command
import Language.LSP.Types.Common
import Language.LSP.Types.Configuration
import Language.LSP.Types.Completion
import Language.LSP.Types.Declaration
import Language.LSP.Types.Definition
import Language.LSP.Types.Diagnostic
import Language.LSP.Types.DocumentColor
import Language.LSP.Types.DocumentHighlight
import Language.LSP.Types.DocumentLink
import Language.LSP.Types.DocumentSymbol
import Language.LSP.Types.FoldingRange
import Language.LSP.Types.Formatting
import Language.LSP.Types.Hover
import Language.LSP.Types.Implementation
import Language.LSP.Types.Initialize
import Language.LSP.Types.Location
import Language.LSP.Types.LspId
import Language.LSP.Types.Method
import Language.LSP.Types.Progress
import Language.LSP.Types.Registration
import Language.LSP.Types.Rename
import Language.LSP.Types.References
import Language.LSP.Types.SelectionRange
import Language.LSP.Types.SignatureHelp
import Language.LSP.Types.TextDocument
import Language.LSP.Types.TypeDefinition
import Language.LSP.Types.Utils
import Language.LSP.Types.Window
import Language.LSP.Types.WatchedFiles
import Language.LSP.Types.WorkspaceEdit
import Language.LSP.Types.WorkspaceFolders
import Language.LSP.Types.WorkspaceSymbol
import qualified Data.HashMap.Strict as HM
import Data.Kind
import Data.Aeson
import Data.Aeson.Types
import Data.Aeson.TH
import Data.GADT.Compare
import Data.Text (Text)
import Data.Type.Equality
import Data.Function (on)
import GHC.Generics
type family MessageParams (m :: Method f t) :: Type where
MessageParams Initialize = InitializeParams
MessageParams Initialized = Maybe InitializedParams
MessageParams Shutdown = Empty
MessageParams Exit = Empty
MessageParams WorkspaceDidChangeWorkspaceFolders = DidChangeWorkspaceFoldersParams
MessageParams WorkspaceDidChangeConfiguration = DidChangeConfigurationParams
MessageParams WorkspaceDidChangeWatchedFiles = DidChangeWatchedFilesParams
MessageParams WorkspaceSymbol = WorkspaceSymbolParams
MessageParams WorkspaceExecuteCommand = ExecuteCommandParams
MessageParams TextDocumentDidOpen = DidOpenTextDocumentParams
MessageParams TextDocumentDidChange = DidChangeTextDocumentParams
MessageParams TextDocumentWillSave = WillSaveTextDocumentParams
MessageParams TextDocumentWillSaveWaitUntil = WillSaveTextDocumentParams
MessageParams TextDocumentDidSave = DidSaveTextDocumentParams
MessageParams TextDocumentDidClose = DidCloseTextDocumentParams
MessageParams TextDocumentCompletion = CompletionParams
MessageParams CompletionItemResolve = CompletionItem
MessageParams TextDocumentHover = HoverParams
MessageParams TextDocumentSignatureHelp = SignatureHelpParams
MessageParams TextDocumentDeclaration = DeclarationParams
MessageParams TextDocumentDefinition = DefinitionParams
MessageParams TextDocumentTypeDefinition = TypeDefinitionParams
MessageParams TextDocumentImplementation = ImplementationParams
MessageParams TextDocumentReferences = ReferenceParams
MessageParams TextDocumentDocumentHighlight = DocumentHighlightParams
MessageParams TextDocumentDocumentSymbol = DocumentSymbolParams
MessageParams TextDocumentCodeAction = CodeActionParams
MessageParams TextDocumentCodeLens = CodeLensParams
MessageParams CodeLensResolve = CodeLens
MessageParams TextDocumentDocumentLink = DocumentLinkParams
MessageParams DocumentLinkResolve = DocumentLink
MessageParams TextDocumentDocumentColor = DocumentColorParams
MessageParams TextDocumentColorPresentation = ColorPresentationParams
MessageParams TextDocumentFormatting = DocumentFormattingParams
MessageParams TextDocumentRangeFormatting = DocumentRangeFormattingParams
MessageParams TextDocumentOnTypeFormatting = DocumentOnTypeFormattingParams
MessageParams TextDocumentRename = RenameParams
MessageParams TextDocumentPrepareRename = PrepareRenameParams
MessageParams TextDocumentFoldingRange = FoldingRangeParams
MessageParams TextDocumentSelectionRange = SelectionRangeParams
MessageParams WindowShowMessage = ShowMessageParams
MessageParams WindowShowMessageRequest = ShowMessageRequestParams
MessageParams WindowLogMessage = LogMessageParams
MessageParams WindowWorkDoneProgressCreate = WorkDoneProgressCreateParams
MessageParams WindowWorkDoneProgressCancel = WorkDoneProgressCancelParams
MessageParams Progress = ProgressParams SomeProgressParams
MessageParams TelemetryEvent = Value
MessageParams ClientRegisterCapability = RegistrationParams
MessageParams ClientUnregisterCapability = UnregistrationParams
MessageParams WorkspaceWorkspaceFolders = Empty
MessageParams WorkspaceConfiguration = ConfigurationParams
MessageParams WorkspaceApplyEdit = ApplyWorkspaceEditParams
MessageParams TextDocumentPublishDiagnostics = PublishDiagnosticsParams
MessageParams CancelRequest = CancelParams
MessageParams CustomMethod = Value
type family ResponseResult (m :: Method f Request) :: Type where
ResponseResult Initialize = InitializeResult
ResponseResult Shutdown = Empty
ResponseResult WorkspaceSymbol = List SymbolInformation
ResponseResult WorkspaceExecuteCommand = Value
ResponseResult TextDocumentWillSaveWaitUntil = List TextEdit
ResponseResult TextDocumentCompletion = List CompletionItem |? CompletionList
ResponseResult CompletionItemResolve = CompletionItem
ResponseResult TextDocumentHover = Maybe Hover
ResponseResult TextDocumentSignatureHelp = SignatureHelp
ResponseResult TextDocumentDeclaration = Location |? List Location |? List LocationLink
ResponseResult TextDocumentDefinition = Location |? List Location |? List LocationLink
ResponseResult TextDocumentTypeDefinition = Location |? List Location |? List LocationLink
ResponseResult TextDocumentImplementation = Location |? List Location |? List LocationLink
ResponseResult TextDocumentReferences = List Location
ResponseResult TextDocumentDocumentHighlight = List DocumentHighlight
ResponseResult TextDocumentDocumentSymbol = List DocumentSymbol |? List SymbolInformation
ResponseResult TextDocumentCodeAction = List (Command |? CodeAction)
ResponseResult TextDocumentCodeLens = List CodeLens
ResponseResult CodeLensResolve = CodeLens
ResponseResult TextDocumentDocumentLink = List DocumentLink
ResponseResult DocumentLinkResolve = DocumentLink
ResponseResult TextDocumentDocumentColor = List ColorInformation
ResponseResult TextDocumentColorPresentation = List ColorPresentation
ResponseResult TextDocumentFormatting = List TextEdit
ResponseResult TextDocumentRangeFormatting = List TextEdit
ResponseResult TextDocumentOnTypeFormatting = List TextEdit
ResponseResult TextDocumentRename = WorkspaceEdit
ResponseResult TextDocumentPrepareRename = Range |? RangeWithPlaceholder
ResponseResult TextDocumentFoldingRange = List FoldingRange
ResponseResult TextDocumentSelectionRange = List SelectionRange
ResponseResult WindowShowMessageRequest = Maybe MessageActionItem
ResponseResult WindowWorkDoneProgressCreate = ()
ResponseResult ClientRegisterCapability = Empty
ResponseResult ClientUnregisterCapability = Empty
ResponseResult WorkspaceWorkspaceFolders = Maybe (List WorkspaceFolder)
ResponseResult WorkspaceConfiguration = List Value
ResponseResult WorkspaceApplyEdit = ApplyWorkspaceEditResponseBody
ResponseResult CustomMethod = Value
data NotificationMessage (m :: Method f Notification) =
NotificationMessage
{ _jsonrpc :: Text
, _method :: SMethod m
, _params :: MessageParams m
} deriving Generic
deriving instance Eq (MessageParams m) => Eq (NotificationMessage m)
deriving instance Show (MessageParams m) => Show (NotificationMessage m)
instance (FromJSON (MessageParams m), FromJSON (SMethod m)) => FromJSON (NotificationMessage m) where
parseJSON = genericParseJSON lspOptions
instance (ToJSON (MessageParams m)) => ToJSON (NotificationMessage m) where
toJSON = genericToJSON lspOptions
toEncoding = genericToEncoding lspOptions
data RequestMessage (m :: Method f Request) = RequestMessage
{ _jsonrpc :: Text
, _id :: LspId m
, _method :: SMethod m
, _params :: MessageParams m
} deriving Generic
deriving instance Eq (MessageParams m) => Eq (RequestMessage m)
deriving instance (Read (SMethod m), Read (MessageParams m)) => Read (RequestMessage m)
deriving instance Show (MessageParams m) => Show (RequestMessage m)
instance (FromJSON (MessageParams m), FromJSON (SMethod m)) => FromJSON (RequestMessage m) where
parseJSON = genericParseJSON lspOptions
instance (ToJSON (MessageParams m), FromJSON (SMethod m)) => ToJSON (RequestMessage m) where
toJSON = genericToJSON lspOptions
toEncoding = genericToEncoding lspOptions
data CustomMessage f t where
ReqMess :: RequestMessage (CustomMethod :: Method f Request) -> CustomMessage f Request
NotMess :: NotificationMessage (CustomMethod :: Method f Notification) -> CustomMessage f Notification
deriving instance Show (CustomMessage p t)
instance ToJSON (CustomMessage p t) where
toJSON (ReqMess a) = toJSON a
toJSON (NotMess a) = toJSON a
instance FromJSON (CustomMessage p Request) where
parseJSON v = ReqMess <$> parseJSON v
instance FromJSON (CustomMessage p Notification) where
parseJSON v = NotMess <$> parseJSON v
data ErrorCode = ParseError
| InvalidRequest
| MethodNotFound
| InvalidParams
| InternalError
| ServerErrorStart
| ServerErrorEnd
| ServerNotInitialized
| UnknownErrorCode
| RequestCancelled
| ContentModified
deriving (Read,Show,Eq)
instance ToJSON ErrorCode where
toJSON ParseError = Number (-32700)
toJSON InvalidRequest = Number (-32600)
toJSON MethodNotFound = Number (-32601)
toJSON InvalidParams = Number (-32602)
toJSON InternalError = Number (-32603)
toJSON ServerErrorStart = Number (-32099)
toJSON ServerErrorEnd = Number (-32000)
toJSON ServerNotInitialized = Number (-32002)
toJSON UnknownErrorCode = Number (-32001)
toJSON RequestCancelled = Number (-32800)
toJSON ContentModified = Number (-32801)
instance FromJSON ErrorCode where
parseJSON (Number (-32700)) = pure ParseError
parseJSON (Number (-32600)) = pure InvalidRequest
parseJSON (Number (-32601)) = pure MethodNotFound
parseJSON (Number (-32602)) = pure InvalidParams
parseJSON (Number (-32603)) = pure InternalError
parseJSON (Number (-32099)) = pure ServerErrorStart
parseJSON (Number (-32000)) = pure ServerErrorEnd
parseJSON (Number (-32002)) = pure ServerNotInitialized
parseJSON (Number (-32001)) = pure UnknownErrorCode
parseJSON (Number (-32800)) = pure RequestCancelled
parseJSON (Number (-32801)) = pure ContentModified
parseJSON _ = mempty
data ResponseError =
ResponseError
{ _code :: ErrorCode
, _message :: Text
, _xdata :: Maybe Value
} deriving (Read,Show,Eq)
deriveJSON lspOptions ''ResponseError
data ResponseMessage (m :: Method f Request) =
ResponseMessage
{ _jsonrpc :: Text
, _id :: Maybe (LspId m)
, _result :: Either ResponseError (ResponseResult m)
} deriving Generic
deriving instance Eq (ResponseResult m) => Eq (ResponseMessage m)
deriving instance Read (ResponseResult m) => Read (ResponseMessage m)
deriving instance Show (ResponseResult m) => Show (ResponseMessage m)
instance (ToJSON (ResponseResult m)) => ToJSON (ResponseMessage m) where
toJSON (ResponseMessage { _jsonrpc = jsonrpc, _id = lspid, _result = result })
= object
[ "jsonrpc" .= jsonrpc
, "id" .= lspid
, case result of
Left err -> "error" .= err
Right a -> "result" .= a
]
instance FromJSON (ResponseResult a) => FromJSON (ResponseMessage a) where
parseJSON = withObject "Response" $ \o -> do
_jsonrpc <- o .: "jsonrpc"
_id <- o .: "id"
_result <- o .:! "result"
_error <- o .:? "error"
result <- case (_error, _result) of
((Just err), Nothing ) -> pure $ Left err
(Nothing , (Just res)) -> pure $ Right res
((Just _err), (Just _res)) -> fail $ "both error and result cannot be present: " ++ show o
(Nothing, Nothing) -> fail "both error and result cannot be Nothing"
return $ ResponseMessage _jsonrpc _id $ result
type family Message (m :: Method f t) :: Type where
Message (CustomMethod :: Method f t) = CustomMessage f t
Message (m :: Method f Request) = RequestMessage m
Message (m :: Method f Notification) = NotificationMessage m
type ClientMessage (m :: Method FromClient t) = Message m
type ServerMessage (m :: Method FromServer t) = Message m
data FromServerMessage' a where
FromServerMess :: forall t (m :: Method FromServer t) a. SMethod m -> Message m -> FromServerMessage' a
FromServerRsp :: forall (m :: Method FromClient Request) a. a m -> ResponseMessage m -> FromServerMessage' a
type FromServerMessage = FromServerMessage' SMethod
instance Eq FromServerMessage where
(==) = (==) `on` toJSON
instance Show FromServerMessage where
show = show . toJSON
instance ToJSON FromServerMessage where
toJSON (FromServerMess m p) = serverMethodJSON m (toJSON p)
toJSON (FromServerRsp m p) = clientResponseJSON m (toJSON p)
fromServerNot :: forall (m :: Method FromServer Notification).
Message m ~ NotificationMessage m => NotificationMessage m -> FromServerMessage
fromServerNot m@NotificationMessage{_method=meth} = FromServerMess meth m
fromServerReq :: forall (m :: Method FromServer Request).
Message m ~ RequestMessage m => RequestMessage m -> FromServerMessage
fromServerReq m@RequestMessage{_method=meth} = FromServerMess meth m
data FromClientMessage' a where
FromClientMess :: forall t (m :: Method FromClient t) a. SMethod m -> Message m -> FromClientMessage' a
FromClientRsp :: forall (m :: Method FromServer Request) a. a m -> ResponseMessage m -> FromClientMessage' a
type FromClientMessage = FromClientMessage' SMethod
instance ToJSON FromClientMessage where
toJSON (FromClientMess m p) = clientMethodJSON m (toJSON p)
toJSON (FromClientRsp m p) = serverResponseJSON m (toJSON p)
fromClientNot :: forall (m :: Method FromClient Notification).
Message m ~ NotificationMessage m => NotificationMessage m -> FromClientMessage
fromClientNot m@NotificationMessage{_method=meth} = FromClientMess meth m
fromClientReq :: forall (m :: Method FromClient Request).
Message m ~ RequestMessage m => RequestMessage m -> FromClientMessage
fromClientReq m@RequestMessage{_method=meth} = FromClientMess meth m
type LookupFunc f a = forall (m :: Method f Request). LspId m -> Maybe (SMethod m, a m)
parseServerMessage :: LookupFunc FromClient a -> Value -> Parser (FromServerMessage' a)
parseServerMessage lookupId v@(Object o) = do
case HM.lookup "method" o of
Just cmd -> do
SomeServerMethod m <- parseJSON cmd
case splitServerMethod m of
IsServerNot -> FromServerMess m <$> parseJSON v
IsServerReq -> FromServerMess m <$> parseJSON v
IsServerEither
| HM.member "id" o
, SCustomMethod cm <- m ->
let m' = (SCustomMethod cm :: SMethod (CustomMethod :: Method FromServer Request))
in FromServerMess m' <$> parseJSON v
| SCustomMethod cm <- m ->
let m' = (SCustomMethod cm :: SMethod (CustomMethod :: Method FromServer Notification))
in FromServerMess m' <$> parseJSON v
Nothing -> do
case HM.lookup "id" o of
Just i' -> do
i <- parseJSON i'
case lookupId i of
Just (m,res) -> clientResponseJSON m $ FromServerRsp res <$> parseJSON v
Nothing -> fail $ unwords ["Failed in looking up response type of", show v]
Nothing -> fail $ unwords ["Got unexpected message without method or id"]
parseServerMessage _ v = fail $ unwords ["parseServerMessage expected object, got:",show v]
parseClientMessage :: LookupFunc FromServer a -> Value -> Parser (FromClientMessage' a)
parseClientMessage lookupId v@(Object o) = do
case HM.lookup "method" o of
Just cmd -> do
SomeClientMethod m <- parseJSON cmd
case splitClientMethod m of
IsClientNot -> FromClientMess m <$> parseJSON v
IsClientReq -> FromClientMess m <$> parseJSON v
IsClientEither
| HM.member "id" o
, SCustomMethod cm <- m ->
let m' = (SCustomMethod cm :: SMethod (CustomMethod :: Method FromClient Request))
in FromClientMess m' <$> parseJSON v
| SCustomMethod cm <- m ->
let m' = (SCustomMethod cm :: SMethod (CustomMethod :: Method FromClient Notification))
in FromClientMess m' <$> parseJSON v
Nothing -> do
case HM.lookup "id" o of
Just i' -> do
i <- parseJSON i'
case lookupId i of
Just (m,res) -> serverResponseJSON m $ FromClientRsp res <$> parseJSON v
Nothing -> fail $ unwords ["Failed in looking up response type of", show v]
Nothing -> fail $ unwords ["Got unexpected message without method or id"]
parseClientMessage _ v = fail $ unwords ["parseClientMessage expected object, got:",show v]
clientResponseJSON :: SClientMethod m -> (HasJSON (ResponseMessage m) => x) -> x
clientResponseJSON m x = case splitClientMethod m of
IsClientReq -> x
IsClientEither -> x
serverResponseJSON :: SServerMethod m -> (HasJSON (ResponseMessage m) => x) -> x
serverResponseJSON m x = case splitServerMethod m of
IsServerReq -> x
IsServerEither -> x
clientMethodJSON :: SClientMethod m -> (ToJSON (ClientMessage m) => x) -> x
clientMethodJSON m x =
case splitClientMethod m of
IsClientNot -> x
IsClientReq -> x
IsClientEither -> x
serverMethodJSON :: SServerMethod m -> (ToJSON (ServerMessage m) => x) -> x
serverMethodJSON m x =
case splitServerMethod m of
IsServerNot -> x
IsServerReq -> x
IsServerEither -> x
type HasJSON a = (ToJSON a,FromJSON a,Eq a)
data ClientNotOrReq (m :: Method FromClient t) where
IsClientNot
:: ( HasJSON (ClientMessage m)
, Message m ~ NotificationMessage m)
=> ClientNotOrReq (m :: Method FromClient Notification)
IsClientReq
:: forall (m :: Method FromClient Request).
( HasJSON (ClientMessage m)
, HasJSON (ResponseMessage m)
, Message m ~ RequestMessage m)
=> ClientNotOrReq m
IsClientEither
:: ClientNotOrReq CustomMethod
data ServerNotOrReq (m :: Method FromServer t) where
IsServerNot
:: ( HasJSON (ServerMessage m)
, Message m ~ NotificationMessage m)
=> ServerNotOrReq (m :: Method FromServer Notification)
IsServerReq
:: forall (m :: Method FromServer Request).
( HasJSON (ServerMessage m)
, HasJSON (ResponseMessage m)
, Message m ~ RequestMessage m)
=> ServerNotOrReq m
IsServerEither
:: ServerNotOrReq CustomMethod
splitClientMethod :: SClientMethod m -> ClientNotOrReq m
splitClientMethod SInitialize = IsClientReq
splitClientMethod SInitialized = IsClientNot
splitClientMethod SShutdown = IsClientReq
splitClientMethod SExit = IsClientNot
splitClientMethod SWorkspaceDidChangeWorkspaceFolders = IsClientNot
splitClientMethod SWorkspaceDidChangeConfiguration = IsClientNot
splitClientMethod SWorkspaceDidChangeWatchedFiles = IsClientNot
splitClientMethod SWorkspaceSymbol = IsClientReq
splitClientMethod SWorkspaceExecuteCommand = IsClientReq
splitClientMethod SWindowWorkDoneProgressCancel = IsClientNot
splitClientMethod STextDocumentDidOpen = IsClientNot
splitClientMethod STextDocumentDidChange = IsClientNot
splitClientMethod STextDocumentWillSave = IsClientNot
splitClientMethod STextDocumentWillSaveWaitUntil = IsClientReq
splitClientMethod STextDocumentDidSave = IsClientNot
splitClientMethod STextDocumentDidClose = IsClientNot
splitClientMethod STextDocumentCompletion = IsClientReq
splitClientMethod SCompletionItemResolve = IsClientReq
splitClientMethod STextDocumentHover = IsClientReq
splitClientMethod STextDocumentSignatureHelp = IsClientReq
splitClientMethod STextDocumentDeclaration = IsClientReq
splitClientMethod STextDocumentDefinition = IsClientReq
splitClientMethod STextDocumentTypeDefinition = IsClientReq
splitClientMethod STextDocumentImplementation = IsClientReq
splitClientMethod STextDocumentReferences = IsClientReq
splitClientMethod STextDocumentDocumentHighlight = IsClientReq
splitClientMethod STextDocumentDocumentSymbol = IsClientReq
splitClientMethod STextDocumentCodeAction = IsClientReq
splitClientMethod STextDocumentCodeLens = IsClientReq
splitClientMethod SCodeLensResolve = IsClientReq
splitClientMethod STextDocumentDocumentLink = IsClientReq
splitClientMethod SDocumentLinkResolve = IsClientReq
splitClientMethod STextDocumentDocumentColor = IsClientReq
splitClientMethod STextDocumentColorPresentation = IsClientReq
splitClientMethod STextDocumentFormatting = IsClientReq
splitClientMethod STextDocumentRangeFormatting = IsClientReq
splitClientMethod STextDocumentOnTypeFormatting = IsClientReq
splitClientMethod STextDocumentRename = IsClientReq
splitClientMethod STextDocumentPrepareRename = IsClientReq
splitClientMethod STextDocumentFoldingRange = IsClientReq
splitClientMethod STextDocumentSelectionRange = IsClientReq
splitClientMethod SCancelRequest = IsClientNot
splitClientMethod SCustomMethod{} = IsClientEither
splitServerMethod :: SServerMethod m -> ServerNotOrReq m
splitServerMethod SWindowShowMessage = IsServerNot
splitServerMethod SWindowShowMessageRequest = IsServerReq
splitServerMethod SWindowLogMessage = IsServerNot
splitServerMethod SWindowWorkDoneProgressCreate = IsServerReq
splitServerMethod SProgress = IsServerNot
splitServerMethod STelemetryEvent = IsServerNot
splitServerMethod SClientRegisterCapability = IsServerReq
splitServerMethod SClientUnregisterCapability = IsServerReq
splitServerMethod SWorkspaceWorkspaceFolders = IsServerReq
splitServerMethod SWorkspaceConfiguration = IsServerReq
splitServerMethod SWorkspaceApplyEdit = IsServerReq
splitServerMethod STextDocumentPublishDiagnostics = IsServerNot
splitServerMethod SCancelRequest = IsServerNot
splitServerMethod SCustomMethod{} = IsServerEither
mEqServer :: SServerMethod m1 -> SServerMethod m2 -> Maybe (m1 :~~: m2)
mEqServer m1 m2 = case (splitServerMethod m1, splitServerMethod m2) of
(IsServerNot, IsServerNot) -> do
Refl <- geq m1 m2
pure HRefl
(IsServerReq, IsServerReq) -> do
Refl <- geq m1 m2
pure HRefl
_ -> Nothing
mEqClient :: SClientMethod m1 -> SClientMethod m2 -> Maybe (m1 :~~: m2)
mEqClient m1 m2 = case (splitClientMethod m1, splitClientMethod m2) of
(IsClientNot, IsClientNot) -> do
Refl <- geq m1 m2
pure HRefl
(IsClientReq, IsClientReq) -> do
Refl <- geq m1 m2
pure HRefl
_ -> Nothing