0 | module Node.Net.Socket
3 | import public Node.Error
4 | import Node.Event.Internal
5 | import Node.Internal.Elab
6 | import Node.Internal.Support
7 | import public Node.Net.Socket.Address
8 | import public Node.Net.Socket.Connect
9 | import public Node.Net.Socket.Type
10 | import public Node.Stream
12 | %language ElabReflection
14 | %foreign "node:lambda: (tys, s, cb) => s.on('close', (b) => cb(b ? _true() : _false())())"
15 | ffi_onClose : s -> (Bool -> PrimIO ()) -> PrimIO ()
18 | socketOnClose : HasIO io => s -> (Bool -> IO ()) -> io ()
19 | socketOnClose s cb = primIO $
ffi_onClose s $
\b => toPrim $
cb b
21 | %foreign nodeOn0 "connect"
22 | ffi_onConnect : s -> PrimIO () -> PrimIO ()
25 | socketOnConnect : HasIO io => s -> IO () -> io ()
26 | socketOnConnect = on0 ffi_onConnect
28 | %foreign nodeOn1 "error"
29 | ffi_onError : s -> (e -> PrimIO ()) -> PrimIO ()
32 | socketOnError : HasIO io => s -> (Error -> IO ()) -> io ()
33 | socketOnError = on1 ffi_onError
41 | (err, addr, family, host) =>
42 | cb(err ? _just(err) : _nothing()
44 | , family ? _just(family) : _nothing()
48 | ffi_onLookup : s -> (Maybe Error -> (address : String) -> (family : Maybe String) -> (host : String) -> PrimIO ()) -> PrimIO ()
51 | socketOnLookup : HasIO io => s -> (Maybe Error -> (address : String) -> (family : Maybe String) -> (host : String) -> IO ()) -> io ()
52 | socketOnLookup s cb = primIO $
ffi_onLookup s $
\err, addr, family, host => toPrim $
cb err addr family host
54 | %foreign nodeOn0 "ready"
55 | ffi_onReady : s -> PrimIO () -> PrimIO ()
58 | socketOnReady : HasIO io => s -> IO () -> io ()
59 | socketOnReady = on0 ffi_onReady
61 | %foreign nodeOn0 "timeout"
62 | ffi_onTimeout : s -> PrimIO () -> PrimIO ()
65 | socketOnTimeout : HasIO io => s -> IO () -> io ()
66 | socketOnTimeout = on0 ffi_onTimeout
71 | const a = s.address()
72 | if (a === undefined || a.port === undefined || a.family === undefined || a.address === undefined) {
78 | ffi_address : s -> PrimIO $
Maybe $
Node Address
81 | socketAddress : HasIO io => s -> io $
Maybe Address
82 | socketAddress s = map fromNode <$> primIO (ffi_address s)
84 | %runElab mkNodeFieldIO (basic "socketBytesRead") "bytesRead" `(Int)
85 | %runElab mkNodeFieldIO (basic "socketBytesWritten") "bytesWritten" `(Int)
87 | %foreign "node:lambda: (tys, s, opts) => s.connect(opts)"
88 | ffi_connect : s -> AnyPtr -> PrimIO s
91 | socketConnect : HasIO io => s -> {auto t : SocketType} -> Connect.options t -> io s
92 | socketConnect s {t} opts = primIO $
ffi_connect s $
believe_me $
convertOptions t opts
94 | %runElab mkNodeFieldIO (basic "socketConnecting") "connecting" `(Bool)
99 | const err = _maybe(e)
100 | return err ? s.destroy(err) : s.destroy()
103 | ffi_destroy : s -> Maybe Error -> PrimIO s
106 | socketDestroy : HasIO io => s -> Maybe Error -> io s
107 | socketDestroy s e = primIO $
ffi_destroy s e
109 | %runElab mkNodeFieldIO (basic "socketDestroyed") "destroyed" `(Bool)
110 | %runElab mkNodeFieldIO (basic "socketLocalAddress") "localAddress" `(Maybe String)
111 | %runElab mkNodeFieldIO (basic "socketLocalPort") "localPort" `(Maybe Int)
112 | %runElab mkNodeFieldIO (basic "socketPending") "pending" `(Bool)
114 | %foreign "node:lambda: (tys, s) => s.ref()"
115 | ffi_ref : s -> PrimIO s
118 | socketRef : HasIO io => s -> io s
119 | socketRef s = primIO $
ffi_ref s
121 | %runElab mkNodeFieldIO (basic "socketRemoteAddress") "remoteAddress" `(Maybe String)
122 | %runElab mkNodeFieldIO (basic "socketRemoteFamily") "remoteFamily" `(Maybe String)
123 | %runElab mkNodeFieldIO (basic "socketRemotePort") "remotePort" `(Maybe Int)
125 | %foreign "node:lambda: (tys, s) => s.resetAndDestroy()"
126 | ffi_resetAndDestroy : s -> PrimIO s
129 | socketResetAndDestroy : HasIO io => s -> io s
130 | socketResetAndDestroy s = primIO $
ffi_resetAndDestroy s
134 | (tys, s, initialDelay) => {
135 | const d = _maybe(initialDelay)
137 | return s.setKeepAlive(true, d)
139 | return s.setKeepAlive(false)
142 | ffi_setKeepAlive : s -> Maybe Int -> PrimIO s
145 | socketSetKeepAlive : HasIO io => s -> Maybe Int -> io s
146 | socketSetKeepAlive s initialDelay = primIO $
ffi_setKeepAlive s initialDelay
148 | %foreign "node:lambda: (tys, s, b) => s.setNoDelay(_bool(b))"
149 | ffi_setNoDelay : s -> Bool -> PrimIO s
152 | socketSetNoDelay : HasIO io => s -> Bool -> io s
153 | socketSetNoDelay s b = primIO $
ffi_setNoDelay s b
157 | (tys, s, timeout) => {
158 | const t = _maybe(timeout)
160 | return s.setTimeout(t)
162 | return s.setTimeout(0)
165 | ffi_setTimeout : s -> Maybe Int -> PrimIO s
168 | socketSetTimeout : HasIO io => s -> Maybe Int -> io s
169 | socketSetTimeout s timeout = primIO $
ffi_setTimeout s timeout
172 | node:lambda: (tys, s) => {
173 | const t = s.timeout
174 | if (t === undefined || t === null) {
180 | ffi_timeout : s -> PrimIO $
Maybe Int
183 | socketTimeout : HasIO io => s -> io $
Maybe Int
184 | socketTimeout s = primIO $
ffi_timeout s
186 | %foreign "node:lambda: (tys, s) => s.unref()"
187 | ffi_unref : s -> PrimIO s
190 | socketUnref : HasIO io => s -> io s
191 | socketUnref s = primIO $
ffi_unref s
193 | %runElab mkNodeFieldIO (basic "socketReadyState") "readyState" `(String)
197 | ReadableClass d Error s =>
198 | WriteableClass d Error s =>
199 | SocketClass (t : SocketType) s | s
202 | (.onClose) : HasIO io => s -> (Bool -> IO ()) -> io ()
203 | (.onClose) = socketOnClose
204 | (.onConnect) : HasIO io => s -> IO () -> io ()
205 | (.onConnect) = socketOnConnect
209 | (.onError) : HasIO io => s -> (Error -> IO ()) -> io ()
210 | (.onError) = socketOnError
211 | (.onLookup) : HasIO io => s -> (Maybe Error -> (address : String) -> (family : Maybe String) -> (host : String) -> IO ()) -> io ()
212 | (.onLookup) = socketOnLookup
213 | (.onReady) : HasIO io => s -> IO () -> io ()
214 | (.onReady) = socketOnReady
215 | (.onTimeout) : HasIO io => s -> IO () -> io ()
216 | (.onTimeout) = socketOnTimeout
217 | (.address) : HasIO io => s -> io $
Maybe Address
218 | (.address) = socketAddress
219 | (.bytesRead) : HasIO io => s -> io Int
220 | (.bytesRead) = socketBytesRead
221 | (.bytesWritten) : HasIO io => s -> io Int
222 | (.bytesWritten) = socketBytesWritten
223 | (.connect) : HasIO io => s -> Connect.options t -> io s
224 | (.connect) s opts = socketConnect s opts { t = t }
225 | (.connecting) : HasIO io => s -> io Bool
226 | (.connecting) = socketConnecting
227 | (.destroy) : HasIO io => s -> Maybe Error -> io s
228 | (.destroy) = socketDestroy
229 | (.destroyed) : HasIO io => s -> io Bool
230 | (.destroyed) = socketDestroyed
232 | (.localAddress) : HasIO io => s -> io $
Maybe String
233 | (.localAddress) = socketLocalAddress
234 | (.localPort) : HasIO io => s -> io $
Maybe Int
235 | (.localPort) = socketLocalPort
237 | (.pending) : HasIO io => s -> io Bool
238 | (.pending) = socketPending
239 | (.ref) : HasIO io => s -> io s
241 | (.remoteAddress) : HasIO io => s -> io $
Maybe String
242 | (.remoteAddress) = socketRemoteAddress
243 | (.remoteFamily) : HasIO io => s -> io $
Maybe String
244 | (.remoteFamily) = socketRemoteFamily
245 | (.remotePort) : HasIO io => s -> io $
Maybe Int
246 | (.remotePort) = socketRemotePort
247 | (.resetAndDestroy) : HasIO io => s -> io s
248 | (.resetAndDestroy) = socketResetAndDestroy
251 | (.setKeepAlive) : HasIO io => s -> Maybe Int -> io s
252 | (.setKeepAlive) = socketSetKeepAlive
253 | (.setNoDelay) : HasIO io => s -> Bool -> io s
254 | (.setNoDelay) = socketSetNoDelay
255 | (.setTimeout) : HasIO io => s -> Maybe Int -> io s
256 | (.setTimeout) = socketSetTimeout
257 | (.timeout) : HasIO io => s -> io $
Maybe Int
258 | (.timeout) = socketTimeout
259 | (.unref) : HasIO io => s -> io s
260 | (.unref) = socketUnref
262 | (.readyState) : HasIO io => s -> io String
263 | (.readyState) = socketReadyState
266 | data Socket : (t : SocketType) -> Type where [external]
269 | implementation ReadableClass d Error (Socket t) where
272 | implementation WriteableClass d Error (Socket t) where
275 | implementation SocketClass TCP (Socket TCP) where
278 | implementation SocketClass IPC (Socket IPC) where
281 | record Options where
282 | constructor MkOptions
284 | allowHalfOpen: Maybe Bool
285 | readable: Maybe Bool
286 | writeable: Maybe Bool
290 | defaultOptions : Options
291 | defaultOptions = MkOptions
293 | , allowHalfOpen = Nothing
294 | , readable = Nothing
295 | , writeable = Nothing
304 | ) => _keepDefined({
306 | allowHalfOpen: _maybeBool(_maybe(allowHalfOpen)),
307 | readable: _maybeBool(_maybe(readable)),
308 | writeable: _maybeBool(_maybe(writeable))
311 | ffi_convertOptions :
313 | -> ( allowHalfOpen : Maybe Bool )
314 | -> ( readable : Maybe Bool )
315 | -> ( writeable : Maybe Bool )
319 | convertOptions : Options -> Node Options
320 | convertOptions o = ffi_convertOptions