{"id":13741228,"url":"https://github.com/synrc/rpc","last_synced_at":"2025-10-09T03:41:25.452Z","repository":{"id":57544924,"uuid":"97171225","full_name":"synrc/rpc","owner":"synrc","description":"☎️ RPC: Type Driven Parser Generator","archived":false,"fork":false,"pushed_at":"2021-11-08T10:50:46.000Z","size":205,"stargazers_count":19,"open_issues_count":4,"forks_count":12,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-09-25T10:02:06.347Z","etag":null,"topics":["java","js","protobuf","swift"],"latest_commit_sha":null,"homepage":"https://rpc.n2o.dev","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/synrc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-13T22:57:34.000Z","updated_at":"2025-03-14T19:55:06.000Z","dependencies_parsed_at":"2022-08-27T04:22:18.047Z","dependency_job_id":null,"html_url":"https://github.com/synrc/rpc","commit_stats":null,"previous_names":["synrc/bert"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/synrc/rpc","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synrc%2Frpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synrc%2Frpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synrc%2Frpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synrc%2Frpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/synrc","download_url":"https://codeload.github.com/synrc/rpc/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/synrc%2Frpc/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277926261,"owners_count":25900535,"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","status":"online","status_checked_at":"2025-10-01T02:00:09.286Z","response_time":88,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["java","js","protobuf","swift"],"created_at":"2024-08-03T04:00:57.026Z","updated_at":"2025-10-09T03:41:25.429Z","avatar_url":"https://github.com/synrc.png","language":"Erlang","funding_links":[],"categories":["Language-Specific"],"sub_categories":["Erlang"],"readme":"RPC: ERLANG API SDK Generators\n==============================\n\n[![Actions Status](https://github.com/synrc/rpc/workflows/mix/badge.svg)](https://github.com/synrc/rpc/actions)\n[![Build Status](https://travis-ci.com/synrc/rpc.svg?branch=master)](https://travis-ci.com/synrc/rpc)\n[![Hex pm](http://img.shields.io/hexpm/v/rpc.svg?style=flat)](https://hex.pm/packages/rpc)\n\nThe main idea is to have unified code of any possible generators for all languages\nfrom HRL Type Specification.\n\nSupported Generators\n--------------------\n\n* Erlang validation according to Type Spec (BERT)\n* JavaScript (BERT)\n* Swift (BERT)\n* Google Protobuf Specification (PROTOBUF)\n\nIntro\n-----\n\nAs you may know, Erlang has its own binary encoding BERT inside\nits virtual machine, called BEAM. For enterprise RPC usually,\nyou use protobuf or MessagePack or Thrift or ASN.1 binary parser\ngenerators. However, as you may know Erlang is not so fast in\nany tasks except moving binaries between sockets. So we at\nSynrc usually use native Erlang BERT encoding on all clients\nwith zero encoding/decoding on server side.\n\nThe encoders/decoders could be of two types: strict (with\nchecking the model for particular type signature with Sums\nand Products) and general which encode/decode anything that\ncan be translated into correct encoding. For example, JavaScript\nencoder/decode generator presented in this repo is just like\nthat (it doesn't check types and constants, given in Erlang\nHRL files). However, Swift version has the ability to check\nencoded/decoded term to comply the Erlang Type Specification.\n\nSamples\n-------\n\nFirst, you can choose the language which is not presented in\nthis repo and try to implement your own BERT enc/dec generator\nfor this language using Swift (Type Spec precise) and\nJavaScript (open relay) generator as examples.\n\nThe aim of this contest is to create encoders/decoders for\neach language and make bridges to other protocol descriptive\nformats like Can'n'Proto or protobuf!\n\nErlang HRL\n----------\n\n```erlang\n-record(error, { code=[] :: [] | binary() }).\n```\n\n```erlang\n-record(ok, { code=[] :: [] | binary() }).\n```\n\n```erlang\n-record(io, { code=[] :: [] | #ok{} | #error{},\n              data=[] :: [] | \u003c\u003c\u003e\u003e \n                | { atom(), binary() | integer() } }).\n```\n\nSwift Model\n-----------\n\n```swift\nclass Err {\n    var code: AnyObject?\n}\n```\n\n```swift\nclass Ok {\n    var code: AnyObject?\n}\n```\n\n```swift\nclass Io {\n    var code: AnyObject?\n    var data: AnyObject?\n}\n```\n\nSwift Spec\n----------\n\n```swift\nChain(types: [\n     Model(value:Tuple(name: \"io\", body: [\n          Model(value:Chain(types: [\n               Model(value: Tuple(name:\"ok\", body: [\n                    Model(value:Atom())])),\n               Model(value: Tuple(name:\"error\", body: [\n                    Model(value:Atom())]))])),\n          Model(value:Tuple(name:\"\", body:[\n               Model(value:Atom()),\n               Model(value:Chain(types: [\n                    Model(value:Binary()),\n                    Model(value:Number())]))]))])) ])\n```\n\nJavaScript\n----------\n\n```javascript\nfunction check() {\n    var res = true;\n    //@TODO: MORE TEST DATA\n    testData = [\n        1,\n        [1, 2, 3],\n        \"string\",\n        {tup: 'io', code: 'login', data: {tup: '$', 0: 'Auth', 1: 12}},\n        {tup: 'io', code: 'login', data: {tup: 'Auth'}},\n        {tup: 'io', code: 'login', data: {tup: '$', 0: 'doe', 1: 12}},\n        {tup: 'Roster', userlist: [{tup: 'Contact'}], status: 'get'},\n        {tup: 'p2p', from: 'john', to: 'doe'},\n        {tup: 'Profile', accounts: [1], status: 'maxim'}\n    ];\n    testData.forEach(function (o) {\n        var o = JSON.stringify(o);\n        var d = JSON.stringify(\n                decode(dec(enc(encode(o)).buffer)))\n                 .replace(/\\\\/g, '');\n\n        if (JSON.stringify(o) != JSON.stringify(\n             decode(dec(enc(encode(o)).buffer)))) {\n            console.log(\"Original: \" + o + \" \u003c=\u003e Decode: \" \n                + d + \" %c [Error]\", \"color: red\");\n            res = false;\n        } else {\n            console.log(\"Data: \" + o + \" %c [OK]\", \"color: green\");\n        }\n    });\n\n    return res;\n}\n```\n\nProtobuf Sample\n---------------\n\nErlang BERT/HRL (source):\n\n```\n-type authType()   :: google_api | facebook_api | mobile |\n                      email | voice | resend | verify | \n                      push | logout | get | delete | clear.\n\n-type authStatus() :: invalid_version | mismatch_user_data |\n                      number_not_allowed | session_not_found |\n                      attempts_expired | invalid_sms_code |\n                      invalid_jwt_code | permission_denied |\n                      invalid_data.\n\n-record('Feature',  { id    = [] :: [] | binary(),\n                      key   = [] :: [] | binary(),\n                      value = [] :: [] | binary(),\n                      group = [] :: [] | binary()}).\n\n-record('Auth',     { client_id   = [] :: [] | binary(),\n                      dev_key     = [] :: [] | binary(),\n                      user_id     = [] :: [] | binary(),\n                      phone       = [] :: [] | binary(),\n                      token       = [] :: [] | binary(),\n                      type        = email :: authStatus(),\n                      sms_code    = [] :: [] | binary(),\n                      attempts    = [] :: [] | integer(),\n                      services    = [] :: list(atom()),\n                      settings    = [] :: list(#'Feature'{}),\n                      push        = [] :: [] | binary(),\n                      os          = [] :: [] | ios | android | web,\n                      created     = [] :: [] | integer(),\n                      last_online = [] :: [] | integer() }).\n```\n\nProto V3 (target):\n\n```\nenum osEnum {\n    ios = 0;\n    android = 1;\n    web = 2;\n}\n\nenum authStatus {\n    invalid_version = 0;\n    mismatch_user_data = 1;\n    number_not_allowed = 2;\n    session_not_found = 3;\n    attempts_expired = 4;\n    invalid_sms_code = 5;\n    invalid_jwt_code = 6;\n    permission_denied = 7;\n    invalid_data = 8;\n}\n\nmessage Feature {\n    string id = 1;\n    string key = 2;\n    string value = 3;\n    string group = 4;\n}\n\nmessage Auth {\n    string client_id = 1;\n    string dev_key = 2;\n    string user_id = 3;\n    string phone = 4;\n    string token = 5;\n    authStatus type = 6;\n    string sms_code = 7;\n    int64 attempts = 8;\n    repeated google.protobuf.Any services = 9;\n    repeated Feature settings = 10;\n    string push = 11;\n    osEnum os = 12;\n    int64 created = 13;\n    int64 last_online = 14;\n}\n```\n\nRun\n---\n\n```\n$ mad com\n==\u003e \"/Users/maxim/depot/synrc/bert\"\nGenerated Protobuf Model: \"priv/protobuf/authType.proto\"\nGenerated Protobuf Model: \"priv/protobuf/authStatus.proto\"\nGenerated Protobuf Model: \"priv/protobuf/Feature.proto\"\nGenerated Protobuf Model: \"priv/protobuf/Auth.proto\"\nGenerated Protobuf Model: \"priv/protobuf/AuthError.proto\"\nCompiling /src/bert_sample.erl\nOK\n```\n\nCredits\n-------\n\n* Yuri Maslovsky — ERLANG\n* Maxim Sokhatsky — GOOGLE, JAVASCRIPT\n* Dmytro Boiko — ERLANG, JAVASCRIPT\n* Anton Makarov — SWIFT\n* Viacheslav Katsuba — JAVASCRIPT\n\nLet's build true native Erlang zero-overhead encoders/decoders for all languages with you!\n\nOM A HUM\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynrc%2Frpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsynrc%2Frpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsynrc%2Frpc/lists"}