# Protobuf-simple
An Haskell implementation of Google's Protocol Buffers version 2 with an
emphasis on simplicity. The implementation consists of a library for encoding
and decoding of data and the `protoc` executable for generating Haskell types
from proto files. In fact, the types that are used in the tests are generated
with the following command:
```
$ protoc data/Types.proto
```
In the example below, the `CustomType` is a Haskell type that was generated
with the `protoc` executable. The `encCustomType` function encodes a CustomType
into a ByteString. The `decCustomType` function decodes a ByteString into
either a CustomType or an error.
```
module Codec where
import Data.ByteString.Lazy (ByteString)
import Data.ProtoBuf (decode, encode)
import Types.CustomType (CustomType(..))
encCustomType :: CustomType -> ByteString
encCustomType = encode
decCustomType :: ByteString -> Either String CustomType
decCustomType = decode
```
The library exposes two modules, Data.ProtoBuf, which is used for encoding and
decoding and Data.ProtoBufInt, which is an internal module that is used by the
generated types.
## Supported Data Types
The following Protocol Buffer types, with their Haskell counterparts, are
supported:
- bool: Bool
- bytes: ByteString (lazy)
- double: Double
- enum: Sum-type
- fixed32: Word32
- fixed64: Word64
- float: Float
- int32: Int32
- int64: Int64
- message: Product-type or newtype
- sfixed32: Int32
- sfixed64: Int64
- sint32: Int32
- sint64: Int64
- string: Text (lazy)
- uint32: Word32
- uint64: Word64
## Compatibility
Besides testing that decoding inverses encoding, the compatibility with other
implementations is tested by decoding binary files that were created with
protobuf-net (C#).
## Other Implementations
There are currently multiple Protocol Buffers implementations available. This
library was created for the following reasons. Firstly, I wanted to use
Data.Text for the string type instead of Data.ByteString as the
protocol-buffers library does. Secondly, I wanted to use newtypes for messages
with only one field. Finally, I wanted to use simpler data types than the
protobuf library does.
For example, the protobuf library uses the following (example from the manual):
```
data Foo = Foo
{ field1 :: Required 1 (Value Int64)
, field2 :: Optional 2 (Value Text)
, field3 :: Repeated 3 (Value Bool)
} deriving (Generic, Show)
```
Whereas protobuf-simple would use the following:
```
data Foo = Foo
{ field1 :: Int64
, field2 :: Maybe Text
, field3 :: Seq Bool
} deriving (Show, Eq, Ord)
```
## Not Implemented
The following Protocol Buffers features are currently not implemented:
- Importing definitions
- Groups
- Declaring extensions in messages
- Declaring nested extensions in messages
- Oneof feature
- Associative maps
- Defining services
- Custom options
## License
Protobuf-simple is released under the MIT License.