Git Product home page Git Product logo

gleam_pb's Introduction

gleam_pb

Protobuf support for Gleam ✨


gleam_pb wraps the excellent gpb erlang library and generates idiomatic Gleam types 🤘

Progress

  • Gleam Type generation
    • custom functions that better handle default values
    • gleam format generated files
    • stop including unnecessary imports
  • message encoding
  • message decoding
  • improve UX
    • call protoc-erl internally
    • flag to better handle gpb header includes
    • helper functions
  • grpc

API

Generated types

gleam_pb generally follows gpb's type generation, but makes it easier to use from Gleam.

protobuf gleam_pb gpb
double,float Float float()
int32, int64, uint32, uint64, sint32, sint64, fixed32, fixed64, sfixed32, sfixed64 Int integer()
bool Bool true | false
enum Zero Paramater Multi Constructor Type atom()
message Option(<CustomType>) record | undefined
string String unicode string
bytes BitString binary()
oneof Option(<CustomType>) with multiple constructors {chosen_field, value}
map unordered list of tuples List(#(Key, Value)) [{key, value}]

Functions

gleam_pb generates functions to make using the types easier

  • function to generate the message with protobuf's default values named new_<custom_type>() -> <CustomType>

  • functions to encode and decode the messages

    • encode_<custom_type>(m: <CustomType>) -> BitString
    • encode_<custom_type>(b: BitString) -> <CustomType>

There are also several other functions intended for usage by gleam_pb

Example

This message

syntax = "proto3";

package protos;

message Example {
    
    message Response {
        int32 val = 1;
        string user = 2;
    }

    enum OptionType {
        foo = 0;
        bar = 1;
        baz = 2;
    }

    repeated OptionType options = 1;

    oneof ResponseOrError {
        Response response = 2;
        string error = 3;
    }
}

Becomes

import gleam/option
import gleam/list
import gleam/pair
import gleam/dynamic
import gleam/erlang/atom
import gleam_pb

/// protos package types generated by gleam_pb
/// DO NOT EDIT
pub type OptionType {
  OptionTypefoo
  OptionTypebar
  OptionTypebaz
}

pub type ExampleResponseOrError {
  ResponseOrErrorresponse(response: option.Option(Response))
  ResponseOrErrorerror(error: String)
}

pub type Example {
  Example(
    options: List(OptionType),
    response_or_error: option.Option(ExampleResponseOrError),
  )
}

pub type Response {
  Response(val: Int, user: String)
}

pub fn new_example() {
  Example(list.new(), option.None)
}

pub fn new_response() {
  Response(0, "")
}

pub fn encode_example(m: Example) -> BitString {
  let name = atom.create_from_string("protos.Example")

  extract_example(name, m)
  |> gleam_pb.encode(name)
}

pub fn decode_example(b: BitString) -> Example {
  let name = atom.create_from_string("protos.Example")
  decode_msg_example(b, name)
  |> reconstruct_example
}

pub fn encode_response(m: Response) -> BitString {
  let name = atom.create_from_string("protos.Example.Response")

  extract_response(name, m)
  |> gleam_pb.encode(name)
}

pub fn decode_response(b: BitString) -> Response {
  let name = atom.create_from_string("protos.Example.Response")
  decode_msg_response(b, name)
  |> reconstruct_response
}

//internal functions continue ...

Usage

gleam_pb and gpb must be used together to generate working Gleam code.

Example Script

# make sure protoc-gen-gleam is in you're path or add it manually using --plugin
protoc --plugin=protoc-gen-gleam -I . --gleam_out="output_path=./src:./src" protos/*.proto

gleam_pb Flags

  • 'output_path': (Required) specifies the desired output path
  • 'protoc_erl_path': path to gpb's protoc-erl
  • 'gpb_header_include': path to prepend to the header include for gpb. See Knwon Issues for more info
    • if you need a variable include here, remember that erlang header resolution is quite clever and can use environment variables
protoc -I . \
  --gleam_out="gpb_header_include=$ENV/include/,output_path=./src,protoc_erl_path=bin/protoc-erl:./src" \
  protos/*.proto

Known Issues

Includes aren't working?!

% generated in `gleam_gpb.erl`
-include("gpb.hrl"). % -> update to point to the correct header post Gleam compilation

gleam_pb's People

Contributors

bwireman avatar sdancer avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.