0 | module System.UV.Stream
2 | import Control.Monad.Trans
3 | import Data.Buffer.Indexed
4 | import Data.ByteString
6 | import IO.Async.Event
8 | import System.UV.Loop
9 | import System.UV.Pointer
10 | import System.UV.Raw.Handle
11 | import System.UV.Raw.Stream
16 | Resource AllocCB where
17 | release = freeAllocCB
20 | data ReadRes : (a : Type) -> Type where
22 | Data : (val : a) -> ReadRes a
23 | Err : UVError -> ReadRes a
26 | Functor ReadRes where
28 | map f (Data val) = Data (f val)
29 | map _ (Err err) = Err err
32 | Applicative ReadRes where
35 | Data f <*> Data a = pure (f a)
37 | Err err <*> _ = Err err
39 | _ <*> Err err = Err err
45 | Err err >>= _ = Err err
48 | data ReadResT : (m : Type -> Type) -> (a : Type) -> Type where
49 | MkReadResT : m (ReadRes a) -> ReadResT m a
52 | runReadResT : ReadResT m a -> m (ReadRes a)
53 | runReadResT (MkReadResT x) = x
56 | Functor m => Functor (ReadResT m) where
57 | map f (MkReadResT x) = MkReadResT $
map f <$> x
60 | Applicative m => Applicative (ReadResT m) where
61 | pure = MkReadResT . pure . pure
62 | MkReadResT f <*> MkReadResT x = MkReadResT [| f <*> x |]
65 | Monad m => Monad (ReadResT m) where
66 | MkReadResT x >>= f = MkReadResT $
do
67 | Data x' <- x | Err err => pure (Err err)
72 | MonadTrans ReadResT where
73 | lift = MkReadResT . map pure
76 | HasIO m => HasIO (ReadResT m) where
77 | liftIO act = MkReadResT $
liftIO act >>= pure . pure
79 | toMsg : Int32 -> Ptr Buf -> IO (ReadRes ByteString)
81 | case uvRes {es = [UVError]} n $> n of
82 | Left (Here EOF) => pure Done
83 | Left (Here err) => pure (Err err)
84 | Right n => Data <$> bufToByteString buf (cast n)
87 | (cc : CloseCB) => Resource (Ptr Stream) where
88 | release h = uv_close h cc
91 | shutdownStream : UVLoop => (0 pc : PCast t Stream) => Ptr t -> Async [] ()
93 | let s := castPtr @{pc} x
94 | in uv_read_stop s >> ignore (uv_shutdown s $
\_,_ => release s)
96 | parameters {auto l : UVLoop}
97 | {auto has : Has UVError es}
103 | -> {auto 0 cstt : PCast t Stream}
104 | -> (Buffer (ReadRes ByteString) -> Async es a)
106 | read {a} ac h run = finally act (uv_read_stop h)
111 | uv $
uv_read_start h ac (\_,n,buf => toMsg n buf >>= buffer st)
115 | write : Ptr t -> (0 _ : PCast t Stream) => ByteString -> Async es ()
117 | use1 (fromByteString b) $
\cs => uvAsync $
\cb =>
118 | uv_write str cs (cast b.size) (\_,_ => cb $
Succeeded ())
123 | -> {auto 0 cst : PCast t Stream}
124 | -> (Buffer (Either UVError $
Ptr Stream) -> Async es a)
126 | listen {a} {cst} server run = do
128 | uv $
uv_listen server 128 $
\p,res =>
129 | buffer q $
if res < 0 then Left $
fromCode res else Right p