-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
1,869 additions
and
560 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
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,3 @@ | ||
language: elm | ||
elm: | ||
- "0.19.0" |
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,27 @@ | ||
Copyright (c) 2018, Erik Timmers | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
|
||
* Redistributions of source code must retain the above copyright notice, this | ||
list of conditions and the following disclaimer. | ||
|
||
* Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
* Neither the name of the copyright holder nor the names of its | ||
contributors may be used to endorse or promote products derived from | ||
this software without specific prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
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,191 @@ | ||
# Protocol Buffers [![Build Status](https://travis-ci.org/eriktim/elm-protocol-buffers.svg?branch=master)](https://travis-ci.org/eriktim/elm-protocol-buffers) | ||
|
||
This package lets you create encoders and decoders for working with | ||
[ProtoBuf](https://developers.google.com/protocol-buffers) messages. Typically, | ||
**you should not use this package directly** as the encoder and decoders can be | ||
generated directly from `.proto` specification files. | ||
|
||
## Motivation | ||
|
||
> Protocol buffers are Google's language-neutral, platform-neutral, extensible | ||
> mechanism for serializing structured data – think XML, but smaller, faster, | ||
> and simpler. You define how you want your data to be structured once, then | ||
> you can use special generated source code to easily write and read your | ||
> structured data to and from a variety of data streams and using a variety of | ||
> languages. | ||
As Evan explained in his vision on | ||
[data interchange](https://gist.github.com/evancz/1c5f2cf34939336ecb79b97bb89d9da6), | ||
there are many ways to send information between clients and servers, like JSON | ||
(optionally according to a specfication, like OpenAPI), GraphQL and the one | ||
this package provides: **ProtoBuf**. | ||
|
||
Where Elm spoils us with an excellent type system, we lose this safety at the | ||
edges of our application when talking to servers. ProtoBuf requires you to | ||
specify the interchange format explicity up front, making it **type-safe**. It | ||
also: | ||
|
||
* makes you **decouple code** for data exchange from your business logic, | ||
enabling your application to evolve over time; | ||
* makes you send **fewer bytes** over the wire; | ||
* allows you to **generate code** using the same data interchange format for | ||
your backend as well! | ||
* is Google's **_lingua franca_** for data | ||
|
||
This package provides an API to help converting between Elm values and bytes by | ||
implementing the ProtoBuf specification. Ultimately, nobody should be writing | ||
these encoders and decoders directly as the required code can be generated | ||
automatically from `.proto` files. This is still a _work-in-progress_. Also | ||
implementing [gRPC](https://grpc.io/docs/guides/index.html) could be an | ||
interesting next step. | ||
|
||
## Example | ||
|
||
Given a ProtoBuf `.proto` file | ||
|
||
```protobuf | ||
message Person { | ||
required string name = 1; | ||
required int32 id = 2; | ||
optional string email = 3; | ||
enum PhoneType { | ||
MOBILE = 0; | ||
HOME = 1; | ||
WORK = 2; | ||
} | ||
message PhoneNumber { | ||
required string number = 1; | ||
optional PhoneType type = 2 [default = HOME]; | ||
} | ||
repeated PhoneNumber phone = 4; | ||
} | ||
``` | ||
|
||
this package handles converting between `Person` and `Bytes` values: | ||
|
||
```elm | ||
import ProtoBuf.Decode as Decode | ||
import ProtoBuf.Encode as Encode | ||
|
||
|
||
|
||
-- MODEL | ||
|
||
|
||
type alias Person = | ||
{ name : String | ||
, id : Int | ||
, email : String | ||
, phone : List PhoneNumber | ||
} | ||
|
||
|
||
type alias PhoneNumber = | ||
{ number : String | ||
, type_ : PhoneType | ||
} | ||
|
||
|
||
type PhoneType | ||
= Mobile | ||
| Home | ||
| Work | ||
|
||
|
||
|
||
-- ENCODE | ||
|
||
|
||
encodePerson : Person -> Encode.Encoder | ||
encodePerson person = | ||
Encode.message | ||
[ ( 1, Encode.string person.name ) | ||
, ( 2, Encode.int32 person.id ) | ||
, ( 3, Encode.string person.email ) | ||
, ( 4, Encode.list encodePhoneNumber person.phone ) | ||
] | ||
|
||
|
||
encodePhoneNumber : PhoneNumber -> Encode.Encoder | ||
encodePhoneNumber phoneNumber = | ||
Encode.message | ||
[ ( 1, Encode.string phoneNumber.number ) | ||
, ( 2, encodePhoneType phoneNumber.type_ ) | ||
] | ||
|
||
|
||
encodePhoneType : PhoneType -> Encode.Encoder | ||
encodePhoneType phoneType = | ||
case phoneType of | ||
Mobile -> | ||
Encode.int32 0 | ||
|
||
Home -> | ||
Encode.int32 1 | ||
|
||
Work -> | ||
Encode.int32 2 | ||
|
||
|
||
|
||
-- DECODE | ||
|
||
|
||
personDecoder : Decode.Decoder Person | ||
personDecoder = | ||
Decode.message Person | ||
|> Decode.required 1 Decode.string | ||
|> Decode.required 2 Decode.int32 | ||
|> Decode.optional 3 Decode.string "" | ||
|> Decode.repeated 4 phoneNumberDecoder | ||
|
||
|
||
phoneNumberDecoder : Decode.Decoder PhoneNumber | ||
phoneNumberDecoder = | ||
Decode.message PhoneNumber | ||
|> Decode.required 1 Decode.string | ||
|> Decode.optional 2 phoneTypeDecoder Home | ||
|
||
|
||
phoneTypeDecoder : Decode.Decoder PhoneType | ||
phoneTypeDecoder = | ||
Decode.int32 | ||
|> Decode.map | ||
(\value -> | ||
case value of | ||
0 -> | ||
Mobile | ||
|
||
1 -> | ||
Home | ||
|
||
2 -> | ||
Work | ||
|
||
_ -> | ||
Home | ||
) | ||
``` | ||
|
||
## Known limitations | ||
|
||
This packages aims to support both `proto2` and `proto3`. However, there are | ||
some limitations. | ||
|
||
* JavaScript uses 64-bit floating point | ||
[numbers](https://tc39.github.io/ecma262/#sec-ecmascript-language-types-number-type) | ||
for both integers and floats. Integers are only considered safe to use up to | ||
about 54 bits. Therefore all 64-bit integer variants are not supported by | ||
this package. | ||
|
||
* Unknown fields are well-formed protocol buffer serialized data representing | ||
fields that the decoder does not recognize (for example when the field is | ||
removed from the `.proto` file but the server is not yet updated). Currently, | ||
these fields are ignored and hence are lost when re-serializing messages. | ||
|
||
* The [any](https://developers.google.com/protocol-buffers/docs/proto3#any) | ||
type is currently not supported. | ||
|
Oops, something went wrong.