Skip to content

Commit 0975966

Browse files
authored
Merge pull request #67 from input-output-hk/tdammers/fix-typed-protocols-doc
Fix typed-protocols-doc
2 parents a357265 + 9426848 commit 0975966

File tree

9 files changed

+154
-178
lines changed

9 files changed

+154
-178
lines changed

cabal.project

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ packages: ./typed-protocols
1919
./typed-protocols-stateful
2020
./typed-protocols-stateful-cborg
2121
./typed-protocols-examples
22-
-- ./typed-protocols-doc
22+
./typed-protocols-doc
2323

2424
test-show-details: direct
2525

@@ -30,3 +30,7 @@ if impl (ghc >= 9.12)
3030
, cborg:ghc-prim
3131
, serialise:base
3232
, serialise:ghc-prim
33+
34+
if(os(windows))
35+
package text
36+
flags: -simdutf

typed-protocols-doc/demo/DemoProtocol.hs

+22-22
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,31 @@
55
{-# LANGUAGE FlexibleInstances #-}
66
{-# LANGUAGE GADTs #-}
77
{-# LANGUAGE MultiParamTypeClasses #-}
8+
{-# LANGUAGE PolyKinds #-}
89
{-# LANGUAGE StandaloneDeriving #-}
910
{-# LANGUAGE TypeApplications #-}
1011
{-# LANGUAGE TypeFamilies #-}
1112
{-# LANGUAGE UndecidableInstances #-}
1213
{-# LANGUAGE ScopedTypeVariables #-}
1314
{-# LANGUAGE TemplateHaskell #-}
1415

16+
-- for `deriveSerDoc`
17+
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
18+
1519
module DemoProtocol
1620
where
1721

18-
import Network.TypedProtocol.Core
19-
import Data.SerDoc.Info
2022
import Control.Monad.Identity
2123
import Control.Monad.Except
24+
2225
import Data.Proxy
23-
import Data.Word
24-
import Data.Typeable
2526
import Data.SerDoc.Class
27+
import Data.SerDoc.Info
2628
import Data.SerDoc.TH
2729
import Data.Text (Text)
30+
import Data.Word
31+
32+
import Network.TypedProtocol.Core
2833

2934
data PongInfo =
3035
PongInfo
@@ -44,34 +49,29 @@ data DemoProtocol a where
4449
-- | End state: either side has terminated the session
4550
EndState :: DemoProtocol a
4651

52+
data SingDemoProtocol a where
53+
SingIdleState :: SingDemoProtocol (IdleState :: DemoProtocol a)
54+
SingAwaitingPongState :: SingDemoProtocol (AwaitingPongState :: DemoProtocol a)
55+
SingEndState :: SingDemoProtocol (EndState :: DemoProtocol a)
56+
57+
instance StateTokenI IdleState where stateToken = SingIdleState
58+
instance StateTokenI AwaitingPongState where stateToken = SingAwaitingPongState
59+
instance StateTokenI EndState where stateToken = SingEndState
60+
4761
instance Protocol (DemoProtocol a) where
4862
data Message (DemoProtocol a) st st' where
4963
PingMessage :: Message (DemoProtocol a) IdleState AwaitingPongState
5064
PongMessage :: Message (DemoProtocol a) AwaitingPongState IdleState
5165
ComplexPongMessage :: Message (DemoProtocol a) AwaitingPongState IdleState
5266
EndMessage :: Message (DemoProtocol a) st EndState
5367

54-
data ServerHasAgency st where
55-
TokIdle :: ServerHasAgency IdleState
56-
57-
data ClientHasAgency st where
58-
TokAwaitingPongState :: ClientHasAgency AwaitingPongState
59-
60-
data NobodyHasAgency st where
61-
TokEnd :: NobodyHasAgency EndState
62-
68+
type StateAgency IdleState = ServerAgency
69+
type StateAgency AwaitingPongState = ClientAgency
70+
type StateAgency EndState = NobodyAgency
6371

64-
exclusionLemma_ClientAndServerHaveAgency tok1 tok2 =
65-
case tok1 of
66-
TokAwaitingPongState -> case tok2 of {}
72+
type StateToken = SingDemoProtocol
6773

68-
exclusionLemma_NobodyAndClientHaveAgency tok1 tok2 =
69-
case tok1 of
70-
TokEnd -> case tok2 of {}
7174

72-
exclusionLemma_NobodyAndServerHaveAgency tok1 tok2 =
73-
case tok1 of
74-
TokEnd -> case tok2 of {}
7575

7676
data DemoCodec a
7777

typed-protocols-doc/src/Network/TypedProtocol/Documentation/DefaultMain.hs

+2-4
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,7 @@ pMainOptions =
6565
)
6666

6767

68-
defaultMain :: ( Codec codec
69-
, HasInfo codec (DefEnumEncoding codec)
68+
defaultMain :: ( HasInfo codec (DefEnumEncoding codec)
7069
, HasInfo codec Word32
7170
) => [ProtocolDescription codec] -> IO ()
7271
defaultMain descriptions = do
@@ -79,8 +78,7 @@ defaultMain descriptions = do
7978
render = getRenderer (moOutputFormat mainOptions) (moOutputFile mainOptions)
8079
write . render $ descriptions
8180

82-
getRenderer :: ( Codec codec
83-
, HasInfo codec (DefEnumEncoding codec)
81+
getRenderer :: ( HasInfo codec (DefEnumEncoding codec)
8482
, HasInfo codec Word32
8583
)
8684
=> OutputFormat

typed-protocols-doc/src/Network/TypedProtocol/Documentation/TH.hs

+20-35
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Control.Monad
1515
-- This import is only needed when 'getDoc' is available.
1616
import Data.Maybe (maybeToList)
1717
#endif
18+
import Data.Maybe (mapMaybe)
1819
import Data.Proxy
1920
import Language.Haskell.TH
2021
import Language.Haskell.TH.Datatype
@@ -34,45 +35,29 @@ describeProtocol protoTyCon protoTyArgs codecTyCon codecTyArgs = do
3435
protoDescription <- getDescription protoTyCon
3536
let pname = nameBase (datatypeName info)
3637

37-
let extractMessageStateNames :: InstanceDec -> [Name]
38-
extractMessageStateNames (DataInstD _ _ _ _ tys _) =
39-
[ case ty of
40-
ForallC _ _ (GadtC _ _ ty') -> go ty'
41-
GadtC _ _ ty' -> go ty'
42-
_ -> error $ "Not a GADT: " ++ show ty
43-
| ty <- tys
44-
]
45-
where
46-
go (PromotedT tyName) = tyName
47-
go (SigT ty' _) = go ty'
48-
go (AppT _ ty') = go ty'
49-
go ty' = error $ "Cannot detect message name from type: " ++ show ty'
50-
extractMessageStateNames i = error $ "Not a DataInstD: " ++ show i
38+
let extractAgency :: InstanceDec -> Maybe Name
39+
extractAgency (TySynInstD (TySynEqn _ _ (PromotedT agency))) = Just agency
40+
extractAgency dec = error $ "Unexpected InstanceDec: " ++ show dec
41+
42+
let extractAgencies :: [InstanceDec] -> [Name]
43+
extractAgencies = mapMaybe extractAgency
44+
45+
let extractTheAgency :: [InstanceDec] -> Name
46+
extractTheAgency inst = case extractAgencies inst of
47+
[agency] -> agency
48+
xs -> error $ "Incorrect number of agencies: " ++ show xs
5149

5250
pstates <- forM (datatypeCons info) $ \conInfo -> do
5351
let conName = constructorName conInfo
5452
stateDescription <- getDescription conName
5553

56-
serverAgencies <- reifyInstances ''ServerHasAgency [ConT conName]
57-
let serverAgencies' =
58-
[ nameBase tyName
59-
| inst <- serverAgencies
60-
, tyName <- extractMessageStateNames inst
61-
, nameBase tyName == nameBase conName
62-
]
63-
clientAgencies <- reifyInstances ''ClientHasAgency [ConT conName]
64-
let clientAgencies' =
65-
[ nameBase tyName
66-
| inst <- clientAgencies
67-
, tyName <- extractMessageStateNames inst
68-
, nameBase tyName == nameBase conName
69-
]
70-
71-
let agencyID = case (serverAgencies', clientAgencies') of
72-
([], []) -> NobodyAgencyID
73-
(_, []) -> ServerAgencyID
74-
([], _) -> ClientAgencyID
75-
_ -> error $ show (nameBase conName, serverAgencies', clientAgencies')
54+
stateAgencies <- reifyInstances ''StateAgency [ConT conName]
55+
let agencyName = extractTheAgency stateAgencies
56+
agencyID = case nameBase agencyName of
57+
"ServerAgency" -> 'ServerAgencyID
58+
"ClientAgency" -> 'ClientAgencyID
59+
"NobodyAgency" -> 'NobodyAgencyID
60+
x -> error $ "Unknown agency type " ++ x ++ " in state " ++ nameBase conName
7661

7762
return (conName, stateDescription, agencyID)
7863

@@ -87,7 +72,7 @@ describeProtocol protoTyCon protoTyArgs codecTyCon codecTyArgs = do
8772
protoDescription
8873
""
8974
$(listE
90-
[ [| ( $(makeState $ ConT conName), stateDescription, agencyID) |]
75+
[ [| ( $(makeState $ ConT conName), stateDescription, $(conE agencyID)) |]
9176
| (conName, stateDescription, agencyID) <- pstates
9277
]
9378
)

0 commit comments

Comments
 (0)