Skip to content

Commit

Permalink
Add MessageEncoding.
Browse files Browse the repository at this point in the history
  • Loading branch information
j6carey committed Dec 3, 2024
1 parent 7c1c679 commit b9ac8ab
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 3 deletions.
3 changes: 3 additions & 0 deletions src/Proto3/Suite/Form/Encode.hs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
module Proto3.Suite.Form.Encode
( MessageEncoder(..)
, toLazyByteString
, MessageEncoding
, cacheMessageEncoder
, cachedMessageEncoding
, Prefix(..)
, Distinct
, fieldsToMessage
Expand Down
41 changes: 38 additions & 3 deletions src/Proto3/Suite/Form/Encode/Core.hs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
module Proto3.Suite.Form.Encode.Core
( MessageEncoder(..)
, toLazyByteString
, MessageEncoding
, cacheMessageEncoder
, cachedMessageEncoding
, Prefix(..)
, Fields
, cachePrefix
Expand Down Expand Up @@ -73,15 +76,43 @@ import Proto3.Wire.Types (FieldNumber(..))

-- | Annotates 'Encode.MessageBuilder' with the type of protobuf message it encodes.
-- Prefix a tag and length to turn the message into a submessage of a larger message.
newtype MessageEncoder (a :: Type) = UnsafeMessageEncoder
newtype MessageEncoder (message :: Type) = UnsafeMessageEncoder
{ untypedMessageEncoder :: Encode.MessageBuilder }

type role MessageEncoder nominal

-- | Serialize a message (or portion thereof) as a lazy 'BL.ByteString'.
toLazyByteString :: forall a . MessageEncoder a -> BL.ByteString
toLazyByteString :: forall message . MessageEncoder message -> BL.ByteString
toLazyByteString = Encode.toLazyByteString . untypedMessageEncoder

-- | The octet sequence that would be emitted by
-- some 'MessageEncoder' having the same type parameter.
--
-- See also: 'cacheMessageEncoder'
newtype MessageEncoding (message :: Type) =
UnsafeMessageEncoding { untypedMessageEncoding :: B.ByteString }

type role MessageEncoding nominal

-- | Precomputes the octet sequence that would be written by the given 'MessageEncoder'.
-- Do this only if you expect to reuse that specific octet sequence repeatedly.
--
-- @'cachedMessageEncoding' . 'cacheMessageEncoder'@ is functionally equivalent to @id@
-- but has different performance characteristics.
--
-- See also: 'cachePrefix'.
cacheMessageEncoder :: MessageEncoder message -> MessageEncoding message
cacheMessageEncoder =
UnsafeMessageEncoding . BL.toStrict . Encode.toLazyByteString . untypedMessageEncoder

-- | Encodes a precomputed 'MessageEncoder' by copying octets from a memory buffer.
-- See 'cacheMessageEncoder'.
--
-- See also: 'cachedFields'
cachedMessageEncoding :: MessageEncoding message -> MessageEncoder message
cachedMessageEncoding = UnsafeMessageEncoder . Encode.unsafeFromByteString . untypedMessageEncoding
{-# INLINE cachedMessageEncoding #-}

-- | A 'Category' on builders that prefix zero or more fields to a message.
-- Use '.' to accumulate prefixes to create an 'MessageEncoder' for a whole message.
--
Expand Down Expand Up @@ -128,13 +159,17 @@ type role Fields nominal nominal nominal
-- | Precomputes the octet sequence that would be written by the given 'Prefix'.
-- Do this only if you expect to reuse that specific octet sequence repeatedly.
--
-- @'cachedFields' . 'cachedPrefix'@ is functionally equivalent to @id@
-- @'cachedFields' . 'cachePrefix'@ is functionally equivalent to @id@
-- but has different performance characteristics.
--
-- See also: 'cacheMessageEncoder'
cachePrefix :: Prefix message possible following -> Fields message possible following
cachePrefix = UnsafeFields . BL.toStrict . Encode.toLazyByteString . untypedPrefix

-- | Encodes a precomputed 'Prefix' by copying octets from a memory buffer.
-- See 'cachePrefix'.
--
-- See also: 'cachedMessageEncoding'.
cachedFields :: Fields message possible following -> Prefix message possible following
cachedFields = UnsafePrefix . Encode.unsafeFromByteString . untypedFields
{-# INLINE cachedFields #-}
Expand Down

0 comments on commit b9ac8ab

Please sign in to comment.