Library for turning Elm values into Protobuf messages.
The examples show
Bytesvalues like this:<3A* 05* 68 65 6C 6C 6F>. The*means the byte is Protobuf metadata. It does not contain any real value. Here3Ameans the next encoded field is a length delimited value for field number7.05is the number of bytes that was used to encode the value that follows. Those five bytes contain the stringhello. Read this if you want to learn more about how Protobuf encoding works.
Describes how to generate a sequence of bytes according to the specification of Protobuf.
Encode a record into a message. For this you need to provide a list of
unique field numbers (between 1 and 536870911) and their corresponding
Encoders.
type alias Foo =
{ a : Float
, b : String
, c : List Int
}
foo : Foo
foo =
Foo 1.25 "hello" [ 1, 2, 3, 4, 5 ]
toEncoder : Encoder
toEncoder =
message
[ ( 1, double foo.a ) -- <09* 00 00 00 00 00 00 F4 3F
, ( 2, string foo.b ) -- 12* 05* 68 65 6C 6C 6F
, ( 3, repeated int32 foo.c ) -- 1A* 05* 01 02 03 04 05>
]Encode integers from -2147483648 to 2147483647 into a message. Uses
variable-length encoding. Inefficient for encoding negative numbers – if your
field is likely to have negative values, use sint32 instead.
encode (int32 0) -- <00>
encode (int32 100) -- <64>
encode (int32 -100) -- <FF FF FF FF FF FF FF 9C>This function can also be used to encode custom types as enumeration:
type Fruit
= Apple
| Banana
| Mango
| Unrecognized Int
toFruitEncoder : Fruit -> Encoder
toFruitEncoder value =
Encode.int32 <|
case value of
Apple ->
0
Banana ->
1
Mango ->
2
Unrecognized v ->
vNote that for proto2 the Unrecognized Int field can be left out.
Encode integers from 0 to 4294967295 into a message.
Uses variable-length encoding.
encode (uint32 0) -- <00>
encode (uint32 100) -- <64>Encode integers from -2147483648 to 2147483647 into a message. Uses
variable-length encoding. These encoder encodes negative numbers more
efficiently than int32.
encode (sint32 0) -- <00>
encode (sint32 100) -- <C8 01>
encode (sint32 -100) -- <C7 01>Encode integers from 0 to 4294967295 into a message. Always four bytes.
More efficient than uint32 if values are often greater than
268435456.
encode (fixed32 0) -- <00 00 00 00>
encode (fixed32 100) -- <64 00 00 00>Encode integers from -2147483648 to 2147483647 into a message.
Always four bytes.
encode (sfixed32 0) -- <00 00 00 00>
encode (sfixed32 100) -- <64 00 00 00>
encode (sfixed32 -100) -- <9C FF FF FF>Encode 64-bit floating point numbers into a message.
encode (double 0) -- <00 00 00 00 00 00 00 00>
encode (double 100) -- <00 00 00 00 00 00 59 40>
encode (double -100) -- <00 00 00 00 00 00 59 C0>Encode 32-bit floating point numbers into a message. The value may lose some precision by encoding it as a float.
encode (float 0) -- <00 00 00 00>
encode (float 100) -- <00 00 C8 42>
encode (float -100) -- <00 00 C8 C2>Encode strings into a message.
encode (string "$20") -- <24 32 30>
encode (string "£20") -- <C2 A3 32 30>
encode (string "€20") -- <E2 82 AC 32 30>
encode (string "bread") -- <62 72 65 61 64>
encode (string "brød") -- <62 72 C3 B8 64>Encode booleans into a message.
encode (bool False) -- <00>
encode (bool True) -- <01>Copy raw Bytes into a message.
-- bs == <0A 0B 0C>
encode (bytes bs) -- <0A 0B 0C>Encode nothing. Note that you can easily combine this encoder with any
field number to pass to message as literally nothing will be
encoded.
This can be useful when encoding embedded messages:
type alias Report =
{ title : String
, contents : String
, attachment : Maybe Attachment
}
toReportEncoder : Report -> Encoder
toReportEncoder report =
message
[ ( 1, string report.title )
, ( 2, string report.contents )
, ( 3, Maybe.withDefault none <| Maybe.map toAttachmentEncoder report.attachment )
]Or when encoding custom types:
type alias FormValue =
{ key : String
, value : Maybe Value
}
type Value
= StringValue String
| IntValue Int
toKeyValueEncoder : FormValue -> Encoder
toKeyValueEncoder formValue =
message
[ ( 1, string formValue.key )
, Maybe.withDefault ( 0, none ) <| Maybe.map toValueEncoder formValue.value
]
toValueEncoder : Value -> ( Int, Encoder )
toValueEncoder model =
case model of
StringValue value ->
( 2, string value )
IntValue value ->
( 3, int32 value )Encode a list of values into a message. Protobuf support two kind of encodings:
-- packed encoding
message
[ ( 1, list int32 [ 1, 2, 3 ] ) -- <0A* 03* 01 02 03>
]
-- non-packed encoding
message
[ ( 1
, list string
[ "one" -- <0A* 03* 6F 6E 65
, "two" -- 0A* 03* 74 77 6F
, "three" -- 0A* 05* 74 68 72 65 65>
]
)
]Packed encoding is preferred as it uses less bytes on the wire. list will
automatically fall-back to non-packed encoding for non-scalar numeric types.
Encode a dictionary of key-value pairs. This requires providing one encoder for the keys and one for the values.
let
value =
Dict.fromList
[ ( 1, "foo" ) -- <0A* 07* 08* 01 12* 03* 66 6F 6F
, ( 2, "bar" ) -- 0A* 07* 08* 02 12* 03* 62 61 72>
]
in
message [ ( 1, dict int32 string value ) ]
Turn an
EncoderintoBytes.Values are encoded together with a field number and the wire type conform the specification in a
.protofile. This allows decoders to know what field it is decoding and to read the right number ofBytes.You probably want to send these
Bytesin the body of an HTTP request: