{"id":16568200,"url":"https://github.com/gfngfn/apbuf","last_synced_at":"2025-10-29T00:31:44.870Z","repository":{"id":48798129,"uuid":"241704307","full_name":"gfngfn/apbuf","owner":"gfngfn","description":"Algebraic protocol buffers","archived":false,"fork":false,"pushed_at":"2021-07-11T18:26:29.000Z","size":375,"stargazers_count":13,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-01T20:44:57.665Z","etag":null,"topics":["elm","json-decoder","json-encoder","json-parser","ocaml","scala","sesterl"],"latest_commit_sha":null,"homepage":"","language":"OCaml","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gfngfn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-02-19T19:17:46.000Z","updated_at":"2023-06-02T00:26:53.000Z","dependencies_parsed_at":"2022-09-23T21:40:20.823Z","dependency_job_id":null,"html_url":"https://github.com/gfngfn/apbuf","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gfngfn%2Fapbuf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gfngfn%2Fapbuf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gfngfn%2Fapbuf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gfngfn%2Fapbuf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gfngfn","download_url":"https://codeload.github.com/gfngfn/apbuf/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238751111,"owners_count":19524528,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elm","json-decoder","json-encoder","json-parser","ocaml","scala","sesterl"],"created_at":"2024-10-11T21:08:37.100Z","updated_at":"2025-10-29T00:31:44.530Z","avatar_url":"https://github.com/gfngfn.png","language":"OCaml","readme":"\n# APBuf (Algebraic Protocol Buffers)\n\n## Summary\n\n*APBuf* (*Algebraic Protocol Buffers*) is a compiler that generates decoders/encoders from a single configuration file that specifies the data format. It is characterized by the native support of “labeled direct sum” (which corresponds to ADTs (= algebraic data types) in Haskell, OCaml, Elm, etc.).\n\nIn exchange for its clean representation, APBuf at least currently does not pursue high computational performance.\n\n* Currently supported target formats:\n  - JSON\n* Currently supported target languages:\n  - Elm\n  - Scala\n  - [Sesterl](https://github.com/gfngfn/Sesterl)\n\n\n## How to install\n\nUnder the condition that `dune` and `make` are installed, invoke:\n\n```console\n$ make install\n```\n\nand then the executable file `apbuf` will be installed.\n\n\n## Example\n\nThe following configuration file:\n\n```\n@language_version \"0.0.1\"\n@output \"elm\": {\n  dir    = \"./gen/elm/src\",\n  module = \"Bar\",\n}\n@output \"scala\": {\n  dir     = \"./gen/play-scala-seed/app/assets/apbuf\",\n  package = \"apbufgen\",\n  object  = \"Bar\",\n}\n\ngeometry :=\n  | Rectangle : rectangle_info(int)\n  | Circle    : circle_info(int, rational)\n\nrectangle_info($num) := {\n  upper_left  : position($num),\n  lower_right : position($num),\n}\n\ncircle_info($cnum, $rnum) := {\n  center : position($cnum),\n  radius : $rnum,\n}\n\nposition($num) := { x : $num, y : $num }\n\nrational := { numerator : int, denominator : int }\n```\n\nproduces Elm code that has the following API:\n\n```elm\nmodule Bar exposing (..)\nimport Json.Decode exposing (Decoder)\nimport Json.Encode exposing (Value)\n\ntype Geometry\n  = Rectangle (RectangleInfo Int)\n  | Circle (CircleInfo Int Rational)\ndecodeGeometry : Decoder Geometry\nencodeGeometry : Geometry -\u003e Value\n\ntype alias RectangleInfo a = { lowerRight : Position a, upperLeft : Position a }\ndecodeRectangleInfo : Decoder a -\u003e Decoder (RectangleInfo a)\nencodeRectangleInfo : (a -\u003e Value) -\u003e RectangleInfo a -\u003e Value\n\ntype alias CircleInfo c r = { center : Position c, radius : r }\ndecodeCircleInfo : Decoder c -\u003e Decoder r -\u003e Decoder (CircleInfo c r)\nencodeCircleInfo : (c -\u003e Value) -\u003e (r -\u003e Value) -\u003e CircleInfo c r -\u003e Value\n\ntype alias Position a = { x : a, y : a }\ndecodePosition : Decoder a -\u003e Decoder (Position a)\nencodePosition : (a -\u003e Value) -\u003e { x : a, y : a } -\u003e Value\n\ntype alias Rational = { denominator : Int, numerator : Int }\ndecodeRational : Decoder Rational\nencodeRational : Rational -\u003e Value\n```\n\nand also generates an implementation of the following API in Scala:\n\n```scala\npackage apbufgen\n\nimport play.api.libs.json._\n\nobject Bar {\n  sealed trait Geometry\n  case class Rectangle(arg: RectangleInfo[Int]) extends Geometry\n  case class Circle(arg: CircleInfo[Int, Rational]) extends Geometry\n  def geometryReads(): Reads[Geometry]\n  def geometryWrites(): Writes[Geometry]\n\n  case class RectangleInfo[Num](lowerRight: Position[Num], upperLeft: Position[Num])\n  def rectangleInfoReads[Num](Reads[Num]): Reads[RectangleInfo[Num]]\n  def rectangleInfoWrites[Num](Writes[Num]): Writes[RectangleInfo[Num]]\n\n  case class CircleInfo[Cnum, Rnum](center: Position[Cnum], radius: Rnum)\n  def circleInfoReads[Cnum, Rnum](Reads[Cnum], Reads[Rnum]): Reads[CircleInfo[Cnum, Rnum]]\n  def circleInfoWrites[Cnum, Rnum](Writes[Cnum], Writes[Rnum]): Writes[CircleInfo[Cnum, Rnum]]\n\n  case class Position[Num](x: Num, y: Num)\n  def positionReads[Num](Reads[Num]): Reads[Position[Num]]\n  def positionWrites[Num](Writes[Num]): Writes[Position[Num]]\n\n  case class Rational(denominator: Int, numerator: Int)\n  def rationalReads(): Reads[Rational]\n  def rationalWrites(): Writes[Rational]\n}\n```\n\n\n## Syntax of configuration files\n\n```\nstringlit ::= (a string literal enclosed by double quotation marks)\nident ::= (a lowercased identifier)\n$x ::= (a lowercased identifier with a preceding dollar sign)\n\ntoplevel ::=\n  | metas decls\n\nmetas ::=\n  | meta metas\n  | (empty)\n\nmeta ::=\n  | '@language_version' stringlit\n  | '@output' stringlit ':' dict\n\ndict ::=\n  | '{' fields '}'\n\nfields ::=\n  | ident '=' metaval ',' fields\n  | ident '=' metaval\n  | (empty)\n\nmetaval ::=\n  | stringlit\n  | '[' metavals ']'\n\nmetavals ::=\n  | metaval ',' metavals\n  | metaval\n  | (empty)\n\n// a list of declarations\ndecls ::=\n  | decl decls\n  | (empty)\n\n// a declaration\ndecl ::=\n  | binder ':=' msg\n  | binder ':=' '{' record '}'\n  | binder ':=' variant\n  | ident ':=' externals\n\nbinder ::=\n  | ident\n  | ident '(' params ')'\n\nparams ::=\n  | $x ',' params\n  | $x ','\n  | $x\n\nmsg ::=\n  | $x\n  | ident\n  | ident '(' args ')'\n\nargs ::=\n  | msg ',' args\n  | msg ','\n  | msg\n\nrecord ::=\n  | ident ':' msg ',' record\n  | ident ':' msg\n  | (empty)\n\nvariant ::=\n  | '|' ctor ':' msg variantsub\n  | ctor ':' msg variantsub\n\nvariantsub ::=\n  | '|' ctor ':' msg variantsub\n  | (empty)\n\nexternals ::=\n  | external externals\n  | (empty)\n\nexternal ::=\n  | '@external' stringlit ':' dict\n```\n\n\n## Features we want to support in the future\n\n* Automated check for asserting backward compatibility of the update of data formats\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgfngfn%2Fapbuf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgfngfn%2Fapbuf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgfngfn%2Fapbuf/lists"}