-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Google Protocol Buffers via GHC.Generics -- @package protobuf @version 0.2.0 -- | Messages containing Optional Enumeration fields fail -- to encode. This module contains orphan instances required to make -- these functional. -- -- For more information reference the associated ticket: -- https://github.com/alphaHeavy/protobuf/issues/3 module Data.ProtocolBuffers.Orphans -- | Data structures that can be folded. -- -- Minimal complete definition: foldMap or foldr. -- -- For example, given a data type -- --
-- data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a) ---- -- a suitable instance would be -- --
-- instance Foldable Tree where -- foldMap f Empty = mempty -- foldMap f (Leaf x) = f x -- foldMap f (Node l k r) = foldMap f l `mappend` f k `mappend` foldMap f r ---- -- This is suitable even for abstract types, as the monoid is assumed to -- satisfy the monoid laws. Alternatively, one could define -- foldr: -- --
-- instance Foldable Tree where -- foldr f z Empty = z -- foldr f z (Leaf x) = f x z -- foldr f z (Node l k r) = foldr f (f k (foldr f z r)) l --class Foldable (t :: * -> *) instance Foldable Last module Data.ProtocolBuffers.Internal -- | Field identifiers type Tag = Word32 -- | A representation of the wire format as described in -- https://developers.google.com/protocol-buffers/docs/encoding#structure data WireField -- | For: int32, int64, uint32, uint64, sint32, sint64, bool, enum VarintField :: {-# UNPACK #-} !Tag -> {-# UNPACK #-} !Word64 -> WireField -- | For: fixed64, sfixed64, double Fixed64Field :: {-# UNPACK #-} !Tag -> {-# UNPACK #-} !Word64 -> WireField -- | For: string, bytes, embedded messages, packed repeated fields DelimitedField :: {-# UNPACK #-} !Tag -> !ByteString -> WireField -- | For: groups (deprecated) StartField :: {-# UNPACK #-} !Tag -> WireField -- | For: groups (deprecated) EndField :: {-# UNPACK #-} !Tag -> WireField -- | For: fixed32, sfixed32, float Fixed32Field :: {-# UNPACK #-} !Tag -> {-# UNPACK #-} !Word32 -> WireField wireFieldTag :: WireField -> Tag getWireField :: Get WireField class EncodeWire a encodeWire :: EncodeWire a => Tag -> a -> Put class DecodeWire a decodeWire :: DecodeWire a => WireField -> Get a zzEncode32 :: Int32 -> Word32 zzEncode64 :: Int64 -> Word64 zzDecode32 :: Word32 -> Int32 zzDecode64 :: Word64 -> Int64 -- | Fields are merely a way to hold a field tag along with its type, this -- shouldn't normally be referenced directly. -- -- This provides better error messages than older versions which used -- Tagged newtype Field (n :: Nat) a Field :: a -> Field a runField :: Field a -> a -- | Value selects the normal/typical way for encoding scalar -- (primitive) values. newtype Value a Value :: a -> Value a runValue :: Value a -> a -- | To provide consistent instances for serialization a Traversable -- Functor is needed to make Required fields have the same -- shape as Optional, Repeated and Packed. -- -- This is the Identity Functor with a Show -- instance. newtype Always a Always :: a -> Always a runAlways :: Always a -> a -- | Enumeration fields use fromEnum and toEnum when -- encoding and decoding messages. newtype Enumeration a Enumeration :: a -> Enumeration a runEnumeration :: Enumeration a -> a -- | RequiredField is a newtype wrapped used to break overlapping -- instances for encoding and decoding values newtype RequiredField a Required :: a -> RequiredField a runRequired :: RequiredField a -> a -- | OptionalField is a newtype wrapped used to break overlapping -- instances for encoding and decoding values newtype OptionalField a Optional :: a -> OptionalField a runOptional :: OptionalField a -> a -- | RepeatedField is a newtype wrapped used to break overlapping -- instances for encoding and decoding values newtype RepeatedField a Repeated :: a -> RepeatedField a runRepeated :: RepeatedField a -> a -- | A Traversable Functor used to select packed sequence -- encoding/decoding. newtype PackedField a PackedField :: a -> PackedField a runPackedField :: PackedField a -> a -- | A list that is stored in a packed format. newtype PackedList a PackedList :: [a] -> PackedList a unPackedList :: PackedList a -> [a] -- | The way to embed a message within another message. These embedded -- messages are stored as length-delimited fields. -- -- For example: -- --
-- data Inner = Inner
-- { innerField :: Required '1' (Value Int64)
-- } deriving (Generic, Show)
--
-- instance Encode Inner
-- instance Decode Inner
--
-- data Outer = Outer
-- { outerField :: Required '1' (Message Inner)
-- } deriving (Generic, Show)
--
-- instance Encode Outer
-- instance Decode Outer
--
--
--
-- It's worth noting that Message a is a Monoid
-- and NFData instance. The Monoid behavior models that of
-- the Protocol Buffers documentation, effectively Last. It's done
-- with a fairly big hammer and it isn't possible to override this
-- behavior. This can cause some less-obvious compile errors for
-- paramterized Message types:
--
--
-- data Inner = Inner{inner :: Required '2' (Value Float)} deriving (Generic, Show)
-- instance Encode Inner
-- instance Decode Inner
--
-- data Outer a = Outer{outer :: Required '3' (Message a)} deriving (Generic, Show)
-- instance Encode a => Encode (Outer a)
-- instance Decode a => Decode (Outer a)
--
--
--
-- This fails because Decode needs to know that the message can be
-- merged. The resulting error implies that you may want to add a
-- constraint to the internal GMessageMonoid class:
--
-- -- /tmp/tst.hs:18:10: -- Could not deduce (protobuf-0.1:GMessageMonoid (Rep a)) -- arising from a use of `protobuf-0.1: Decode .$gdmdecode' -- from the context (Decode a) -- bound by the instance declaration at /tmp/tst.hs:18:10-39 -- Possible fix: -- add an instance declaration for -- (protobuf-0.1:GMessageMonoid (Rep a)) -- In the expression: -- (protobuf-0.1:Decode.$gdmdecode) -- In an equation for decode: -- decode = (protobuf-0.1:Decode .$gdmdecode) -- In the instance declaration for `'Decode' (Outer a)' ---- -- The correct fix is to add the Monoid constraint for the -- message: -- --
-- - instance (Encode a) => Decode (Outer a) -- + instance (Monoid (Message a), Decode a) => Decode (Outer a) --newtype Message m Message :: m -> Message m runMessage :: Message m -> m -- | An implementation of Protocol Buffers in pure Haskell. -- -- Extensive documentation is available at -- https://developers.google.com/protocol-buffers/docs/overview -- and Google's reference implementation can be found at -- http://code.google.com/p/protobuf/. -- -- It is intended to be used via GHC.Generics and does not require -- .proto files to function. Tools are being developed that -- will convert a Haskell Protobuf definition into a .proto -- and vise versa. -- -- Given a message definition: -- --
-- {-# LANGUAGE DeriveGeneric #-}
--
-- import Data.Int
-- import Data.ProtocolBuffers
-- import Data.Text
-- import GHC.Generics (Generic)
-- import GHC.TypeLits
--
-- data Foo = Foo
-- { field1 :: Required '1' (Value Int64) -- ^ The last field with tag = 1
-- , field2 :: Optional '2' (Value Text) -- ^ The last field with tag = 2
-- , field3 :: Repeated '3' (Value Bool) -- ^ All fields with tag = 3, ordering is preserved
-- } deriving (Generic, Show)
--
-- instance Encode Foo
-- instance Decode Foo
--
--
--
-- It can then be used for encoding and decoding. The Encode and
-- Decode instances are derived automatically using DeriveGeneric
-- and DefaultSignatures as outlined here:
-- http://www.haskell.org/haskellwiki/GHC.Generics#More_general_default_methods.
--
-- To construct a message, use putField to set each field value.
-- Optional, Repeated and Packed fields can be set
-- to their empty value by using mempty. An example using record
-- syntax for clarity:
--
--
-- >>> let msg = Foo{field1 = putField 42, field2 = mempty, field3 = putField [True, False]}
--
--
-- To serialize a message first convert it into a Put by way of
-- encodeMessage and then to a ByteString by using
-- runPut. Lazy ByteString serialization is done with
-- runPutLazy.
--
-- -- >>> fmap hex runPut $ encodeMessage msg -- "082A18011800" ---- -- Decoding is done with the inverse functions: decodeMessage and -- runGet, or runGetLazy. -- --
-- >>> runGet decodeMessage =<< unhex "082A18011800" :: Either String Foo
-- Right
-- (Foo
-- { field1 = Field {runField = Required {runRequired = Always {runAlways = Value {runValue = 42}}}}
-- , field2 = Field {runField = Optional {runOptional = Last {getLast = Nothing}}}
-- , field3 = Field {runField = Repeated {runRepeated = [Value {runValue = True},Value {runValue = False}]}}
-- }
-- )
--
--
-- Use getField to read fields from a message:
--
-- -- >>> let Right msg = runGet decodeMessage =<< unhex "082A18011800" :: Either String Foo -- -- >>> getField $ field1 msg -- 42 -- -- >>> getField $ field2 msg -- Nothing -- -- >>> getField $ field3 msg -- [True,False] ---- -- Some Protocol Buffers features are not currently implemented: -- --
-- getField :: Required '1' (Value Text) -> Text -- putField :: Text -> Required '1' (Value Text) -- -- getField :: Optional '2' (Value Int32) -> Maybe Int32 -- putField :: Maybe Int32 -> Optional '2' (Value Int32) -- -- getField :: Repeated '3' (Value Double) -> [Double] -- putField :: [Double] -> Repeated '3' (Value Double) -- -- getField :: Packed '4' (Value Word64) -> [Word64] -- putField :: [Word64] -> Packed '4' (Value Word64) -- --class HasField a where type family FieldType a :: * field f = fmap putField . f . getField getField :: HasField a => a -> FieldType a putField :: HasField a => FieldType a -> a field :: (HasField a, Functor f) => (FieldType a -> f (FieldType a)) -> a -> f a -- | Fields are merely a way to hold a field tag along with its type, this -- shouldn't normally be referenced directly. -- -- This provides better error messages than older versions which used -- Tagged data Field (n :: Nat) a -- | Value selects the normal/typical way for encoding scalar -- (primitive) values. data Value a -- | Enumeration fields use fromEnum and toEnum when -- encoding and decoding messages. data Enumeration a -- | The way to embed a message within another message. These embedded -- messages are stored as length-delimited fields. -- -- For example: -- --
-- data Inner = Inner
-- { innerField :: Required '1' (Value Int64)
-- } deriving (Generic, Show)
--
-- instance Encode Inner
-- instance Decode Inner
--
-- data Outer = Outer
-- { outerField :: Required '1' (Message Inner)
-- } deriving (Generic, Show)
--
-- instance Encode Outer
-- instance Decode Outer
--
--
--
-- It's worth noting that Message a is a Monoid
-- and NFData instance. The Monoid behavior models that of
-- the Protocol Buffers documentation, effectively Last. It's done
-- with a fairly big hammer and it isn't possible to override this
-- behavior. This can cause some less-obvious compile errors for
-- paramterized Message types:
--
--
-- data Inner = Inner{inner :: Required '2' (Value Float)} deriving (Generic, Show)
-- instance Encode Inner
-- instance Decode Inner
--
-- data Outer a = Outer{outer :: Required '3' (Message a)} deriving (Generic, Show)
-- instance Encode a => Encode (Outer a)
-- instance Decode a => Decode (Outer a)
--
--
--
-- This fails because Decode needs to know that the message can be
-- merged. The resulting error implies that you may want to add a
-- constraint to the internal GMessageMonoid class:
--
-- -- /tmp/tst.hs:18:10: -- Could not deduce (protobuf-0.1:GMessageMonoid (Rep a)) -- arising from a use of `protobuf-0.1: Decode .$gdmdecode' -- from the context (Decode a) -- bound by the instance declaration at /tmp/tst.hs:18:10-39 -- Possible fix: -- add an instance declaration for -- (protobuf-0.1:GMessageMonoid (Rep a)) -- In the expression: -- (protobuf-0.1:Decode.$gdmdecode) -- In an equation for decode: -- decode = (protobuf-0.1:Decode .$gdmdecode) -- In the instance declaration for `'Decode' (Outer a)' ---- -- The correct fix is to add the Monoid constraint for the -- message: -- --
-- - instance (Encode a) => Decode (Outer a) -- + instance (Monoid (Message a), Decode a) => Decode (Outer a) --data Message m -- | Signed integers are stored in a zz-encoded form. newtype Signed a Signed :: a -> Signed a -- | Fixed integers are stored in little-endian form without additional -- encoding. newtype Fixed a Fixed :: a -> Fixed a