forked from google/proto-lens
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Data.ProtoLens.Any for storing arbitrary Messages.
Fixes google#22. Provides simple `pack` and `unpack` functions. Since the `unpack` operation is partial (and has multiple types of "failure"), I wasn't sure how to fit it into a `Lens`; so I left that alone for the time being. I turned this into a minor version bump. It does add a new field to `MessageDescriptor` which usually requires a major bump; but since that field is internal to codegen, it shouldn't break any individual users.
- Loading branch information
Showing
15 changed files
with
221 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
{-# LANGUAGE OverloadedStrings #-} | ||
{-# LANGUAGE ScopedTypeVariables #-} | ||
module Data.ProtoLens.Any | ||
( Any | ||
, pack | ||
, packWithPrefix | ||
, unpack | ||
, UnpackError(..) | ||
) where | ||
|
||
import Control.Exception (Exception(..)) | ||
import Data.Monoid ((<>)) | ||
import Data.Text (Text, breakOnEnd) | ||
import Data.Typeable (Typeable) | ||
import Data.ProtoLens | ||
( decodeMessage | ||
, def | ||
, encodeMessage | ||
, Message(..) | ||
, MessageDescriptor(..) | ||
) | ||
import Lens.Family2 ((&), (.~), (^.)) | ||
import Proto.Google.Protobuf.Any | ||
|
||
-- | Packs the given message into an 'Any' using the default type URL prefix | ||
-- "type.googleapis.com". | ||
pack :: forall a . Message a => a -> Any | ||
pack = packWithPrefix googleApisPrefix | ||
|
||
googleApisPrefix :: Text | ||
googleApisPrefix = "type.googleapis.com" | ||
|
||
|
||
-- | Packs the given message into an 'Any' using the given type URL prefix. | ||
packWithPrefix :: forall a . Message a => Text -> a -> Any | ||
packWithPrefix prefix x = | ||
def & typeUrl .~ (prefix <> "/" <> name) | ||
& value .~ encodeMessage x | ||
where | ||
name = messageName (descriptor :: MessageDescriptor a) | ||
|
||
|
||
data UnpackError | ||
= DifferentType | ||
{ expectedMessageType :: Text -- ^ The expected @packagename.messagename@ | ||
, actualUrl :: Text -- ^ The typeUrl in the 'Any' being unpacked | ||
} | ||
| DecodingError String -- ^ The error from decodeMessage | ||
deriving (Show, Eq, Typeable) | ||
|
||
instance Exception UnpackError | ||
|
||
-- | Unpacks the given 'Any' into the given message type. Returns 'Nothing' | ||
-- if the type doesn't match or parsing the payload has failed. | ||
-- | ||
-- Ignores the type URL prefix. | ||
unpack :: forall a . Message a => Any -> Either UnpackError a | ||
unpack a | ||
| expectedName /= snd (breakOnEnd "/" $ a ^. typeUrl) | ||
= Left DifferentType | ||
{ expectedMessageType = expectedName | ||
, actualUrl = a ^. typeUrl | ||
} | ||
| otherwise = case decodeMessage (a ^. value) of | ||
Left e -> Left $ DecodingError e | ||
Right x -> Right x | ||
where | ||
expectedName = messageName (descriptor :: MessageDescriptor a) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.