-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Google Protocol Buffers via GHC.Generics -- -- Google Protocol Buffers via GHC.Generics. -- -- Protocol Buffers are a way of encoding structured data in an efficient -- yet extensible format. Google uses Protocol Buffers for almost all of -- its internal RPC protocols and file formats. -- -- This library supports a useful subset of Google Protocol Buffers -- message specifications in a Haskell. No preprocessor or additional -- build steps are required for message encoding and decoding. -- -- Record specifications are built by defining records with specially -- defined fields that capture most of the Protocol Buffers specification -- language. @package protobuf @version 0.1 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 :: *) 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 D1 (Value Int64)
-- } deriving (Generic, Show)
--
-- instance Encode Inner
-- instance Decode Inner
--
-- data Outer = Outer
-- { outerField :: Required D1 (Message Inner)
-- } deriving (Generic, Show)
--
-- instance Encode Outer
-- instance Decode Outer
--
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.
--
-- The Data.TypeLevel dependency is required due to
-- http://hackage.haskell.org/trac/ghc/ticket/7459. I believe the
-- partial fix already committed will allow migrating to
-- GHC.TypeLits once GHC 7.8.1 is released.
--
-- Given a message definition:
--
--
-- {-# LANGUAGE DeriveGeneric #-}
--
-- import Data.Int
-- import Data.ProtocolBuffers
-- import Data.TypeLevel (D1, D2, D3)
-- import Data.Text
-- import GHC.Generics (Generic)
--
-- data Foo = Foo
-- { field1 :: Required D1 (Value Int64) -- ^ The last field with tag = 1
-- , field2 :: Optional D2 (Value Text) -- ^ The last field with tag = 2
-- , field3 :: Repeated D3 (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.
--
-- 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 D1 (Value Text) -> Text -- putField :: Text -> Required D1 (Value Text) -- -- getField :: Optional D2 (Value Int32) -> Maybe Int32 -- putField :: Maybe Int32 -> Optional D2 (Value Int32) -- -- getField :: Repeated D3 (Value Double) -> [Double] -- putField :: [Double] -> Repeated D3 (Value Double) -- -- getField :: Packed D4 (Value Word64) -> [Word64] -- putField :: [Word64] -> Packed D4 (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 :: *) 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 D1 (Value Int64)
-- } deriving (Generic, Show)
--
-- instance Encode Inner
-- instance Decode Inner
--
-- data Outer = Outer
-- { outerField :: Required D1 (Message Inner)
-- } deriving (Generic, Show)
--
-- instance Encode Outer
-- instance Decode Outer
--
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