protobuf
| Kind | kit |
|---|---|
| Categories | data-format serialization encoding |
| Keywords | protobuf protocol-buffers serialization grpc binary |
Protocol Buffers binary serialization for Kit
Files
| File | Description |
|---|---|
.editorconfig | Editor formatting configuration |
.gitignore | Git ignore rules for build artifacts and dependencies |
.tool-versions | asdf tool versions (Zig, Kit) |
LICENSE | MIT license file |
README.md | This file |
examples/basic.kit | Basic usage example |
examples/nested.kit | Nested message example |
examples/person.kit | Complete person/address-book style example |
examples/repeated.kit | Repeated and packed field example |
kit.toml | Package manifest with metadata and dependencies |
src/protobuf.kit | Kit Protobuf - Protocol Buffers binary serialization |
tests/protobuf.test.kit | API and behavior tests |
tests/types.test.kit | Type and constructor tests |
Dependencies
No Kit package dependencies.
This is a pure Kit package. It does not require protoc, generated code, or native FFI libraries.
Installation
kit add gitlab.com/kit-lang/packages/kit-protobuf.gitUsage
import Kit.Protobuf as Protobuf
main = fn =>
# Build a message with:
# field 1: int32 id = 150
# field 2: string name = "testing"
message = [
Protobuf.field 1 (Protobuf.int 150),
Protobuf.field 2 (Protobuf.string "testing")
]
# Encode fields to protobuf wire-format bytes
bytes = Protobuf.encode message
println "Encoded: ${Protobuf.bytes-to-hex bytes}"
# Decode bytes back into field records
match Protobuf.decode bytes
| Err err ->
println "Decode error: ${err}"
| Ok fields ->
match Protobuf.get-field fields 1
| Some value ->
match Protobuf.as-int value
| Some id -> println "id: ${Int.to-string id}"
| None -> println "field 1 is not an int"
| None -> println "field 1 not found"
match Protobuf.get-field fields 2
| Some value ->
match Protobuf.as-string value
| Some name -> println "name: ${name}"
| None -> println "field 2 is not a string"
| None -> println "field 2 not found"
mainNested Messages
import Kit.Protobuf as Protobuf
address = [
Protobuf.field 1 (Protobuf.string "123 Main St"),
Protobuf.field 2 (Protobuf.string "Springfield")
]
person = [
Protobuf.field 1 (Protobuf.int 42),
Protobuf.field 2 (Protobuf.string "Alice"),
Protobuf.field 3 (Protobuf.message address)
]
bytes = Protobuf.encode personRepeated Fields
import Kit.Protobuf as Protobuf
# Non-packed repeated strings are encoded as repeated fields with the same number.
tags = [
Protobuf.field 1 (Protobuf.string "kit"),
Protobuf.field 1 (Protobuf.string "protobuf")
]
# Packed repeated integers are encoded as one length-delimited field.
numbers = [
Protobuf.field 2 (Protobuf.packed-ints [1, 2, 3, 100, 300])
]API Notes
encode accepts a List Field and returns encoded bytes as List Int.
decode, as-message, and as-packed-ints return Kit Result values using Ok and Err.
Field values are built with helpers such as int, uint, sint, bool, enum, fixed32, fixed64, string, bytes, message, repeated-values, and packed-ints.
Decoded values can be extracted with as-int, as-sint, as-bool, as-fixed32, as-fixed64, as-bytes, as-string, as-message, and as-packed-ints.
Length-delimited fields decode to BytesValue by default. Use as-string for UTF-8/ASCII string fields, or as-message for embedded messages.
The implementation supports protobuf wire types for varint, fixed32, fixed64, and length-delimited values. Deprecated group wire types are recognized but return decode errors.
Development
Running Examples
Run examples with the interpreter:
kit run examples/basic.kit
kit run examples/nested.kit
kit run examples/repeated.kit
kit run examples/person.kitCompile an example to a native binary:
kit build examples/basic.kit -o basic && ./basicRunning Tests
Run the test suite:
kit testRun the test suite with coverage:
kit test --coverageRunning kit dev
Run the standard development workflow (format, check, and test):
kit devThis will:
- Check formatting
- Type check source and examples
- Run tests with coverage
Running Parity Checks
Compare interpreter output against compiled binary output for examples:
kit parity --failures-onlyUse --no-spinner in CI or scripted runs:
kit parity --no-spinner --failures-onlyGenerating Documentation
Generate API documentation from doc comments:
kit docNote: Kit sources with doc comments (##) will generate HTML documents in docs/*.html.
Cleaning Build Artifacts
Remove generated files, caches, and build artifacts:
kit task cleanNote: Defined in kit.toml.
Local Installation
To install this package locally for development:
kit installThis installs the package to ~/.kit/packages/@kit/protobuf/, making it available for import as Kit.Protobuf in other projects.
When changing src/protobuf.kit, reinstall or otherwise refresh the local package copy before testing examples that import Kit.Protobuf.
License
This package is released under the MIT License - see LICENSE for details.
Exported Functions & Types
ProtobufError
Protobuf error type with specific variants for different failure modes.
Variants
ProtobufEncodeError {message}ProtobufDecodeError {message}WireType
Protocol buffer wire types (encoding format identifiers).
Variants
VarintFixed64LengthDelimStartGroupEndGroupFixed32FieldValue
Field value variants for different protobuf types.
Variants
VarintValue {Int}Fixed32Value {Int}Fixed64Value {Int}BytesValue {List, Int}StringValue {String}MessageValue {List, Field}RepeatedValue {List, FieldValue}PackedValue {List, Int}IntDecodeResult
Internal result types for decoding with remaining bytes.
Variants
IntDecodeOk {IntWithRest}IntDecodeErr {String}FieldType
Field type descriptors for schema definitions.
Variants
TInt32TInt64TUint32TUint64TSint32TSint64TBoolTEnumTFixed32TSfixed32TFloatTFixed64TSfixed64TDoubleTStringTBytesTMessageTRepeated {FieldType}TPacked {FieldType}varint
WireType
fixed64
WireType
length-delim
WireType
fixed32
WireType
int32
FieldType
int64
FieldType
uint32
FieldType
uint64
FieldType
sint32
FieldType
sint64
FieldType
bool-type
FieldType
enum-type
FieldType
fixed32-type
FieldType
sfixed32
FieldType
float-type
FieldType
fixed64-type
FieldType
sfixed64
FieldType
double-type
FieldType
string-type
FieldType
bytes-type
FieldType
message-type
FieldType
repeated
FieldType -> FieldType
packed
FieldType -> FieldType
field-def
PositiveInt -> NonEmptyString -> FieldType -> FieldDef
message-def
NonEmptyString -> List FieldDef -> MessageDef
encode-field
Encode a single field to bytes.
Parameters:
Returns:
PositiveInt -> FieldValue -> List Int
bytes = encode-field 1 (int 42)
# Returns: [8, 42] (tag for field 1 varint, value 42)encode
Encode a complete protobuf message to bytes.
Parameters:
Returns:
List Field -> List Int
fields = [field 1 (int 42), field 2 (string "hello")]
bytes = encode fieldsdecode
Decode a complete protobuf message from bytes.
Parameters:
Returns:
List Int -> Result (List Field) ProtobufError
match decode bytes
| Ok fields -> print "Decoded ${Int.to-string (List.length fields)} fields"
| Err err -> print "Error: ${err}"int
Create a varint integer field value (int32/int64/uint32/uint64).
Parameters:
Returns:
Int -> FieldValue
uint
Create an unsigned varint integer field value (alias for int).
Parameters:
Returns:
Int -> FieldValue
sint
Create a signed varint integer field value with zigzag encoding (sint32/sint64).
Parameters:
Returns:
Int -> FieldValue
bool
Create a boolean field value (encoded as varint 0 or 1).
Parameters:
Returns:
Bool -> FieldValue
enum
Create an enum field value (encoded as varint).
Parameters:
Returns:
Int -> FieldValue
fixed32
Create a fixed32 field value (fixed32/sfixed32/float).
Parameters:
Returns:
Int -> FieldValue
sfixed32
Create a signed fixed32 field value (alias for fixed32).
Parameters:
Returns:
Int -> FieldValue
fixed64
Create a fixed64 field value (fixed64/sfixed64/double).
Parameters:
Returns:
Int -> FieldValue
sfixed64
Create a signed fixed64 field value (alias for fixed64).
Parameters:
Returns:
Int -> FieldValue
string
Create a string field value.
Parameters:
Returns:
String -> FieldValue
bytes
Create a bytes field value.
Parameters:
Returns:
List Int -> FieldValue
message
Create a nested message field value.
Parameters:
Returns:
List Field -> FieldValue
repeated-values
Create a repeated field value (non-packed).
Parameters:
Returns:
List FieldValue -> FieldValue
packed-ints
Create a packed repeated integer field value.
Parameters:
Returns:
List Int -> FieldValue
get-field
Get a field by number from decoded message fields.
Parameters:
Returns:
List Field -> PositiveInt -> Option FieldValue
match get-field decoded-fields 1
| Some value -> print "Found field 1"
| None -> print "Field 1 not found"get-repeated
Get all fields with a given number (for repeated fields).
Parameters:
Returns:
List Field -> PositiveInt -> List FieldValue
repeated-values = get-repeated decoded-fields 3
print "Found ${Int.to-string (List.length repeated-values)} values"as-int
Extract varint as integer.
Parameters:
Returns:
FieldValue -> Option Int
as-sint
Extract varint as signed integer (with zigzag decoding).
Parameters:
Returns:
FieldValue -> Option Int
as-bool
Extract varint as boolean.
Parameters:
Returns:
FieldValue -> Option Bool
as-fixed32
Extract fixed32 value.
Parameters:
Returns:
FieldValue -> Option Int
as-fixed64
Extract fixed64 value.
Parameters:
Returns:
FieldValue -> Option Int
as-bytes
Extract bytes value.
Parameters:
Returns:
FieldValue -> Option (List Int)
as-string
Extract string value.
Parameters:
Returns:
FieldValue -> Option String
as-message
Extract embedded message as fields.
Parameters:
Returns:
FieldValue -> Result (List Field) ProtobufError
as-packed-ints
Extract packed repeated integers.
Parameters:
Returns:
FieldValue -> Result (List Int) ProtobufError
field
Create a Field record from field number and value.
Parameters:
Returns:
PositiveInt -> FieldValue -> Field
f = field 1 (int 42)
# Creates: { number: 1, wire-type: Varint, value: VarintValue 42 }bytes-to-hex
Format bytes as hex string for debugging.
Parameters:
Returns:
List Int -> String
hex = bytes-to-hex [8, 42, 18, 5]
print "Encoded: ${hex}"inspect
Print decoded message structure for debugging.
Parameters:
Returns:
List Field -> Unit
inspect decoded-fields
# Prints:
# Field 1:
# varint: 42
# Field 2:
# string: "hello"