@@ -19,14 +19,12 @@ const
19
19
20
20
type
21
21
LPProtoHandler * = proc (
22
- conn: Connection ,
23
- proto: string ):
24
- Future [void ]
25
- {.gcsafe , raises : [].}
22
+ conn: Connection ,
23
+ proto: string ): Future [void ] {.async .}
26
24
27
25
LPProtocol * = ref object of RootObj
28
26
codecs* : seq [string ]
29
- handler * : LPProtoHandler # # this handler gets invoked by the protocol negotiator
27
+ handlerImpl : LPProtoHandler # # invoked by the protocol negotiator
30
28
started* : bool
31
29
maxIncomingStreams: Opt [int ]
32
30
@@ -52,23 +50,59 @@ proc `maxIncomingStreams=`*(p: LPProtocol, val: int) =
52
50
p.maxIncomingStreams = Opt .some (val)
53
51
54
52
func codec * (p: LPProtocol ): string =
55
- assert (p.codecs.len > 0 , " Codecs sequence was empty!" )
53
+ doAssert (p.codecs.len > 0 , " Codecs sequence was empty!" )
56
54
p.codecs[0 ]
57
55
58
56
func `codec=` * (p: LPProtocol , codec: string ) =
59
57
# always insert as first codec
60
58
# if we use this abstraction
61
59
p.codecs.insert (codec, 0 )
62
60
61
+ template `handler` * (p: LPProtocol ): LPProtoHandler =
62
+ p.handlerImpl
63
+
64
+ template `handler` * (
65
+ p: LPProtocol , conn: Connection , proto: string ): Future [void ] =
66
+ p.handlerImpl (conn, proto)
67
+
68
+ func `handler=` * (p: LPProtocol , handler: LPProtoHandler ) =
69
+ p.handlerImpl = handler
70
+
71
+ # Callbacks that are annotated with `{.async: (raises).}` explicitly
72
+ # document the types of errors that they may raise, but are not compatible
73
+ # with `LPProtoHandler` and need to use a custom `proc` type.
74
+ # They are internally wrapped into a `LPProtoHandler`, but still allow the
75
+ # compiler to check that their `{.async: (raises).}` annotation is correct.
76
+ # https://github.com/nim-lang/Nim/issues/23432
77
+ func `handler=` * [E](
78
+ p: LPProtocol ,
79
+ handler: proc (
80
+ conn: Connection ,
81
+ proto: string ): InternalRaisesFuture [void , E]) =
82
+ proc wrap (conn: Connection , proto: string ): Future [void ] {.async .} =
83
+ await handler (conn, proto)
84
+ p.handlerImpl = wrap
85
+
63
86
proc new * (
64
- T: type LPProtocol ,
65
- codecs: seq [string ],
66
- handler: LPProtoHandler ,
67
- maxIncomingStreams: Opt [int ] | int = Opt .none (int )): T =
87
+ T: type LPProtocol ,
88
+ codecs: seq [string ],
89
+ handler: LPProtoHandler ,
90
+ maxIncomingStreams: Opt [int ] | int = Opt .none (int )): T =
68
91
T (
69
92
codecs: codecs,
70
- handler : handler,
93
+ handlerImpl : handler,
71
94
maxIncomingStreams:
72
95
when maxIncomingStreams is int : Opt .some (maxIncomingStreams)
73
96
else : maxIncomingStreams
74
97
)
98
+
99
+ proc new * [E](
100
+ T: type LPProtocol ,
101
+ codecs: seq [string ],
102
+ handler: proc (
103
+ conn: Connection ,
104
+ proto: string ): InternalRaisesFuture [void , E],
105
+ maxIncomingStreams: Opt [int ] | int = Opt .none (int )): T =
106
+ proc wrap (conn: Connection , proto: string ): Future [void ] {.async .} =
107
+ await handler (conn, proto)
108
+ T.new (codec, wrap, maxIncomingStreams)
0 commit comments