git.iko.soy/rowtype-yoga/purescript-arraybuffer-builder
on 1103087 help sign in
157 lines 6.0 kB history raw
1-- | This module provides a `Builder` monoid and a `PutM` monad
2-- | for serializing `Data.ArrayBuffer.Types.ArrayBuffer`s.
3-- | See the package README for usage examples.
4-- |
5-- | Writing to an `ArrayBuffer` is an `Effect`ful activity, so most
6-- | functions in this module must be run in a `MonadEffect` context.
7-- |
8-- | For operations for working with `ArrayBuffer`, see
9-- | module
10-- | [`Data.ArrayBuffer.ArrayBuffer`](https://pursuit.purescript.org/packages/purescript-arraybuffer/docs/Data.ArrayBuffer.ArrayBuffer)
11-- | in package __purescript-arraybuffer__.
12module Data.ArrayBuffer.Builder
13( PutM
14, Put
15, execPutM
16, execPut
17, subBuilder
18, putArrayBuffer
19, putDataView
20, putDataBuff
21, putUint8
22, putInt8
23, putUint16be
24, putUint16le
25, putInt16be
26, putInt16le
27, putUint32be
28, putUint32le
29, putInt32be
30, putInt32le
31, putFloat32be
32, putFloat32le
33, putFloat64be
34, putFloat64le
35, module Data.ArrayBuffer.Builder.Internal
37where
39import Prelude
41import Control.Monad.Rec.Class (class MonadRec)
42import Control.Monad.Writer.Trans (WriterT, execWriterT, tell, lift)
43import Data.ArrayBuffer.Builder.Internal (Builder, DataBuff(..), length, toView, (<>>))
44import Data.ArrayBuffer.Builder.Internal as Internal
45import Data.ArrayBuffer.Types (ArrayBuffer, DataView)
46import Data.Float32 (Float32)
47import Data.UInt (UInt)
48import Effect (Effect)
49import Effect.Class (class MonadEffect)
51-- | The `PutM` monad is a `WriterT Builder` transformer monad which
52-- | gives us do-notation for the `Builder` monoid. The base monad must be
53-- | a `MonadEffect`.
54-- |
55-- | To append `Builder`s in this monad call `tell`, or any of the `put*`
56-- | functions in this module.
57type PutM = WriterT Builder
59-- | The `PutM` type reified to `Effect`, in other words `WriterT Builder Effect`.
60type Put = PutM Effect
62-- | Build an `ArrayBuffer` with do-notation in any `MonadEffect`. *O(n)* Stack-safe.
63execPutM :: forall m. MonadEffect m => MonadRec m => PutM m Unit -> m ArrayBuffer
64execPutM = Internal.execBuilder <=< execWriterT
66-- | Build an `ArrayBuffer` with do-notation in `Effect`. *O(n)* Stack-safe.
67execPut :: Put Unit -> Effect ArrayBuffer
68execPut = execPutM
70-- | Build up a sub-`Builder` without `tell`ing it to the `Writer` yet.
71-- |
72-- | One case where we might want to call a `subBuilder` is when
73-- | serializing length-prefixed messages in some protocol. In that case,
74-- | we must serialize the message first, calculate the message length,
75-- | append the message length, and then append the message.
76-- |
77-- | In a `PutM` monad do-block, we can
78-- |
79-- | ```
80-- | do
81-- | messageBuilder <- subBuilder $ do
82-- | putField1
83-- | putField2
84-- |
85-- | putInt32be $ length messageBuilder
86-- | tell messageBuilder
87-- | ```
88subBuilder :: forall m. Monad m => PutM m Unit -> PutM m Builder
89subBuilder = lift <<< execWriterT
91-- | Append an `ArrayBuffer` to the builder.
92putArrayBuffer :: forall m. Monad m => ArrayBuffer -> PutM m Unit
93putArrayBuffer = tell <<< Internal.singleton <<< Internal.Buff
95-- | Append a `DataView` to the builder.
96putDataView :: forall m. Monad m => DataView -> PutM m Unit
97putDataView = tell <<< Internal.singleton <<< Internal.View
99-- | Append either an `ArrayBuffer` or a `DataView` to the builder.
100putDataBuff :: forall m. Monad m => DataBuff -> PutM m Unit
101putDataBuff = tell <<< Internal.singleton
103-- | Append an 8-bit unsigned integer (byte) to the builder.
104putUint8 :: forall m. MonadEffect m => UInt -> PutM m Unit
105putUint8 = putArrayBuffer <=< Internal.encodeUint8
107-- | Append an 8-bit two’s-complement signed integer (char) to the builder.
108putInt8 :: forall m. MonadEffect m => Int -> PutM m Unit
109putInt8 = putArrayBuffer <=< Internal.encodeInt8
111-- | Append a 16-bit big-endian unsigned integer to the builder.
112putUint16be :: forall m. MonadEffect m => UInt -> PutM m Unit
113putUint16be = putArrayBuffer <=< Internal.encodeUint16be
115-- | Append a 16-bit little-endian unsigned integer to the builder.
116putUint16le :: forall m. MonadEffect m => UInt -> PutM m Unit
117putUint16le = putArrayBuffer <=< Internal.encodeUint16le
119-- | Append a 16-bit big-endian two’s-complement signed integer to the builder.
120putInt16be :: forall m. MonadEffect m => Int -> PutM m Unit
121putInt16be = putArrayBuffer <=< Internal.encodeInt16be
123-- | Append a 16-bit little-endian two’s-complement signed integer to the builder.
124putInt16le :: forall m. MonadEffect m => Int -> PutM m Unit
125putInt16le = putArrayBuffer <=< Internal.encodeInt16le
127-- | Append a 32-bit big-endian unsigned integer to the builder.
128putUint32be :: forall m. MonadEffect m => UInt -> PutM m Unit
129putUint32be = putArrayBuffer <=< Internal.encodeUint32be
131-- | Append a 32-bit little-endian unsigned integer to the builder.
132putUint32le :: forall m. MonadEffect m => UInt -> PutM m Unit
133putUint32le = putArrayBuffer <=< Internal.encodeUint32le
135-- | Append a 32-bit big-endian two’s-complement signed integer to the builder.
136putInt32be :: forall m. MonadEffect m => Int -> PutM m Unit
137putInt32be = putArrayBuffer <=< Internal.encodeInt32be
139-- | Append a 32-bit little-endian two’s-complement signed integer to the builder.
140putInt32le :: forall m. MonadEffect m => Int -> PutM m Unit
141putInt32le = putArrayBuffer <=< Internal.encodeInt32le
143-- | Append a 32-bit big-endian IEEE single-precision float to the builder.
144putFloat32be :: forall m. MonadEffect m => Float32 -> PutM m Unit
145putFloat32be = putArrayBuffer <=< Internal.encodeFloat32be
147-- | Append a 32-bit little-endian IEEE single-precision float to the builder.
148putFloat32le :: forall m. MonadEffect m => Float32 -> PutM m Unit
149putFloat32le = putArrayBuffer <=< Internal.encodeFloat32le
151-- | Append a 64-bit big-endian IEEE double-precision float to the builder.
152putFloat64be :: forall m. MonadEffect m => Number -> PutM m Unit
153putFloat64be = putArrayBuffer <=< Internal.encodeFloat64be
155-- | Append a 64-bit little-endian IEEE double-precision float to the builder.
156putFloat64le :: forall m. MonadEffect m => Number -> PutM m Unit
157putFloat64le = putArrayBuffer <=< Internal.encodeFloat64le