{"id":26286553,"url":"https://github.com/asimov-platform/protoflow","last_synced_at":"2025-05-07T16:42:26.331Z","repository":{"id":248310890,"uuid":"828351531","full_name":"asimov-platform/protoflow","owner":"asimov-platform","description":"🚧 Protoflow implements flow-based programming (FBP) for Rust using Protocol Buffers messages.","archived":false,"fork":false,"pushed_at":"2024-12-17T12:12:29.000Z","size":675,"stargazers_count":29,"open_issues_count":8,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-12-17T13:18:58.643Z","etag":null,"topics":["fbp","flow","protobuf","protoflow"],"latest_commit_sha":null,"homepage":"https://crates.io/crates/protoflow","language":"Rust","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/asimov-platform.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-13T21:49:24.000Z","updated_at":"2024-12-17T12:12:31.000Z","dependencies_parsed_at":"2024-11-05T10:29:43.123Z","dependency_job_id":"fc0987dc-e85e-4806-8744-a2c5fe330f29","html_url":"https://github.com/asimov-platform/protoflow","commit_stats":null,"previous_names":["artob/protoflow","asimovplatform/protoflow","asimov-platform/protoflow"],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asimov-platform%2Fprotoflow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asimov-platform%2Fprotoflow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asimov-platform%2Fprotoflow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/asimov-platform%2Fprotoflow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/asimov-platform","download_url":"https://codeload.github.com/asimov-platform/protoflow/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243642067,"owners_count":20323953,"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":["fbp","flow","protobuf","protoflow"],"created_at":"2025-03-14T20:30:59.179Z","updated_at":"2025-03-14T20:32:16.643Z","avatar_url":"https://github.com/asimov-platform.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Protoflow\n\n[![License](https://img.shields.io/badge/license-Public%20Domain-blue.svg)](https://unlicense.org)\n[![Compatibility](https://img.shields.io/badge/rust-1.70%2B-blue)](https://rust-lang.org)\n[![Package](https://img.shields.io/crates/v/protoflow)](https://crates.io/crates/protoflow)\n[![Documentation](https://img.shields.io/docsrs/protoflow?label=docs.rs)](https://docs.rs/protoflow/latest/protoflow/)\n\n_\"Τὰ πάντα ῥεῖ καὶ οὐδὲν μένει\" — Heraclitus_\n\n**Protoflow** is a [Rust] implementation of [flow-based programming] (FBP),\nwith messages encoded as [Protocol Buffers]. It can be used to implement\ndataflow systems consisting of interconnected blocks that process messages.\n\n\u003e [!TIP]\n\u003e 🚧 _We are building in public. This is presently under heavy construction._\n\n- [Features](#-features)\n- [Prerequisites](#%EF%B8%8F-prerequisites)\n- [Installation](#%EF%B8%8F-installation)\n- [Examples](#-examples)\n- [Reference](#-reference)\n- [Development](#-development)\n\n## ✨ Features\n\n- Implements a flow-based programming (FBP) dataflow scheduler.\n- Constructs systems by connecting reusable components called blocks.\n- Uses Protocol Buffers messages for inter-block communication.\n- Currently offers a threaded runtime with an in-process transport.\n- Planned support for pluggable runtimes (threaded, async, etc).\n- Planned support for pluggable transports (in-process, socket, etc).\n- Includes a command-line interface (CLI) for executing Protoflow blocks.\n- Supports opting out of any feature using comprehensive feature flags.\n- Adheres to the Rust API Guidelines in its [naming conventions].\n- 100% free and unencumbered public domain software.\n\n## 🛠️ Prerequisites\n\n- [Rust](https://rust-lang.org) 1.70+\n\n## ⬇️ Installation\n\n### Installation via Cargo\n\n```bash\ncargo install protoflow\n```\n\n### Installation via Homebrew\n\n```bash\nbrew tap asimov-platform/tap\nbrew install protoflow --HEAD\n```\n\n## 👉 Examples\n\n### Examples for Rust\n\nFor Rust examples, see the [`examples`] directory. Good places to start are\nthe [`echo_lines`] and [`count_lines`] examples:\n\n```bash\ncargo run --example echo_lines \u003c CHANGES.md\ncargo run --example count_lines \u003c README.md\n```\n\n#### The [`count_lines`] example\n\n```rust filename=\"lib/protoflow/examples/count_lines/main.rs\"\nuse protoflow::{blocks::*, BlockResult};\n\npub fn main() -\u003e BlockResult {\n    System::run(|s| {\n        let stdin = s.read_stdin();\n\n        let line_decoder = s.decode_lines();\n        s.connect(\u0026stdin.output, \u0026line_decoder.input);\n\n        let counter = s.count::\u003cString\u003e();\n        s.connect(\u0026line_decoder.output, \u0026counter.input);\n\n        let count_encoder = s.encode_lines();\n        s.connect(\u0026counter.count, \u0026count_encoder.input);\n\n        let stdout = s.write_stdout();\n        s.connect(\u0026count_encoder.output, \u0026stdout.input);\n    })\n}\n```\n\n## 📚 Reference\n\n### Glossary\n\n- **System**: A collection of blocks that are connected together.\n  Systems are the top-level entities in a Protoflow program.\n\n- **Block**: An encapsulated system component that processes messages.\n  Blocks are the autonomous units of computation in a system.\n\n- **Port**: A named connection point on a block that sends or receives\n  messages. Ports are the only interfaces through which blocks communicate\n  with each other.\n\n- **Message**: A unit of data that flows between blocks in a system.\n  Messages are Protocol Buffers packets that are processed by blocks.\n\n### Blocks\n\nThe built-in blocks provided by Protoflow are listed below:\n\n| Block             | Description                                                                                                                    |\n|:------------------|:-------------------------------------------------------------------------------------------------------------------------------|\n| [`Buffer`]        | Stores all messages it receives.                                                                                               |\n| [`ConcatStrings`] | Concatenates the received string messages, with an optional delimiter string inserted between each message.                    |\n| [`Const`]         | Sends a constant value.                                                                                                        |\n| [`Count`]         | Counts the number of messages it receives, while optionally passing them through.                                              |\n| [`Decode`]        | Decodes messages from a byte stream.                                                                                           |\n| [`DecodeCSV`]     | Decodes the received input bytes message into a structured CSV format, separating the header and rows as `prost_types::Value`. |\n| [`DecodeHex`]     | Decodes hexadecimal stream to byte stream.                                                                                     |\n| [`DecodeJSON`]    | Decodes JSON messages from a byte stream.                                                                                      |\n| [`Delay`]         | Passes messages through while delaying them by a fixed or random duration.                                                     |\n| [`Drop`]          | Discards all messages it receives.                                                                                             |\n| [`Encode`]        | Encodes messages to a byte stream.                                                                                             |\n| [`EncodeCSV`]     | Encodes the provided header and rows, given as `prost_types::Value`, into a CSV-formatted byte stream.                         |\n| [`EncodeHex`]     | Encodes a byte stream into hexadecimal form.                                                                                   |\n| [`EncodeJSON`]    | Encodes messages into JSON format.                                                                                             |\n| [`Hash`]          | Computes the cryptographic hash of a byte stream.                                                                              |\n| [`Random`]        | Generates and sends a random value.                                                                                            |\n| [`ReadDir`]       | Reads file names from a file system directory.                                                                                 |\n| [`ReadEnv`]       | Reads the value of an environment variable.                                                                                    |\n| [`ReadFile`]      | Reads bytes from the contents of a file.                                                                                       |\n| [`ReadSocket`]    | Reads bytes from a TCP socket.                                                                                                 |\n| [`ReadStdin`]     | Reads bytes from standard input (aka stdin).                                                                                   |\n| [`SplitString`]   | Splits the received input message, with an optional delimiter string parameter.                                                |\n| [`WriteFile`]     | Writes or appends bytes to the contents of a file.                                                                             |\n| [`WriteSocket`]   | Writes bytes to a TCP socket                                                                                                   |\n| [`WriteStderr`]   | Writes bytes to standard error (aka stderr).                                                                                   |\n| [`WriteStdout`]   | Writes bytes to standard output (aka stdout).                                                                                  |\n\n#### [`Buffer`]\n\nA block that simply stores all messages it receives.\n\n```mermaid\nblock-beta\n    columns 4\n    Source space:2 Buffer\n    Source-- \"input\" --\u003eBuffer\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class Buffer block\n    class Source hidden\n```\n\n```bash\nprotoflow execute Buffer\n```\n\n#### [`ConcatStrings`]\n\nA block for concatenating all string messages it receives, with an optional delimiter string inserted between each message\n\n```mermaid\nblock-beta\n    columns 7\n    Source space:2 ConcatStrings space:2 Sink\n    Source-- \"input\" --\u003eConcatStrings\n    ConcatStrings-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class ConcatStrings block\n    class Source hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute ConcatStrings delimiter=\",\"\n```\n\n#### [`Const`]\n\nA block for sending a constant value.\n\n```mermaid\nblock-beta\n    columns 4\n    Const space:2 Sink\n    Const-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class Const block\n    class Sink hidden\n```\n\n```bash\nprotoflow execute Const value=Hello\n```\n\n#### [`Count`]\n\nA block that counts the number of messages it receives, while optionally passing them through.\n\n```mermaid\nblock-beta\n    columns 7\n    Source space:2 Count space:2 Sink\n    space:7\n    space:7\n    space:3 Result space:3\n    Source-- \"input\" --\u003eCount\n    Count-- \"output\" --\u003eSink\n    Count-- \"count\" --\u003eResult\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class Count block\n    class Source hidden\n    class Sink hidden\n    class Result hidden\n```\n\n```bash\nprotoflow execute Count\n```\n\n#### [`Decode`]\n\nA block that decodes `T` messages from a byte stream.\n\n```mermaid\nblock-beta\n    columns 7\n    Source space:2 Decode space:2 Sink\n    Source-- \"input\" --\u003eDecode\n    Decode-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class Decode block\n    class Source hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute Decode encoding=text\n```\n\n#### [`DecodeCSV`]\n\nA block that decodes CSV files from a byte stream into a header and rows represented as `prost_types::Value`\n\n```mermaid\nblock-beta\n    columns 7\n    space:5 Sink1 space:1\n    space:1 Source space:1 DecodeCSV space:3\n    space:5 Sink2 space:1\n    Source-- \"input\" --\u003eDecodeCSV\n    DecodeCSV-- \"header\" --\u003eSink1\n    DecodeCSV-- \"content\" --\u003eSink2\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class DecodeCSV block\n    class Source hidden\n    class Sink1 hidden\n    class Sink2 hidden\n```\n\n```bash\nprotoflow execute DecodeCSV\n```\n\n#### [`DecodeHex`]\n\nA block that decodes a hexadecimal byte stream into bytes\n\n```mermaid\nblock-beta\n    columns 7\n    Source space:2 DecodeHex space:2 Sink\n    Source-- \"input\" --\u003eDecodeHex\n    DecodeHex-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class DecodeHex block\n    class Source hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute DecodeHex\n```\n\n#### [`DecodeJSON`]\n\nA block that decodes JSON messages from a byte stream.\n\n```mermaid\nblock-beta\n    columns 7\n    Source space:2 DecodeJSON space:2 Sink\n    Source-- \"input\" --\u003eDecodeJSON\n    DecodeJSON-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class DecodeJSON block\n    class Source hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute DecodeJSON\n```\n\n#### [`Delay`]\n\nA block that passes messages through while delaying them by a fixed or random duration.\n\n```mermaid\nblock-beta\n    columns 7\n    Source space:2 Delay space:2 Sink\n    Source-- \"input\" --\u003eDelay\n    Delay-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class Delay block\n    class Source hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute Delay fixed=2\n```\n\n#### [`Drop`]\n\nA block that simply discards all messages it receives.\n\n```mermaid\nblock-beta\n    columns 4\n    Source space:2 Drop\n    Source-- \"input\" --\u003eDrop\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class Drop block\n    class Source hidden\n```\n\n```bash\nprotoflow execute Drop\n```\n\n#### [`Encode`]\n\nA block that encodes `T` messages to a byte stream.\n\n```mermaid\nblock-beta\n    columns 7\n    Source space:2 Encode space:2 Sink\n    Source-- \"input\" --\u003eEncode\n    Encode-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class Encode block\n    class Source hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute Encode encoding=text\nprotoflow execute Encode encoding=protobuf\n```\n\n#### [`EncodeCSV`]\n\nA block that encodes CSV files by converting a header and rows, provided as `prost_types::Value` streams, into a byte stream\n\n```mermaid\nblock-beta\n    columns 7\n    space:1 Source1 space:5\n    space:3 EncodeCSV space:1 Sink space:1\n    space:1 Source2 space:5\n    Source1-- \"header\" --\u003eEncodeCSV\n    Source2-- \"rows\" --\u003eEncodeCSV\n    EncodeCSV-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class EncodeCSV block\n    class Source1 hidden\n    class Source2 hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute EncodeCSV\n```\n\n#### [`EncodeHex`]\n\nA block that encodes a byte stream into hexadecimal form.\n\n```mermaid\nblock-beta\n    columns 7\n    Source space:2 EncodeHex space:2 Sink\n    Source-- \"input\" --\u003eEncodeHex\n    EncodeHex-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class EncodeHex block\n    class Source hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute EncodeHex\n```\n\n#### [`EncodeJSON`]\n\nA block that encodes messages into JSON format.\n\n```mermaid\nblock-beta\n    columns 7\n    Source space:2 EncodeJSON space:2 Sink\n    Source-- \"input\" --\u003eEncodeJSON\n    EncodeJSON-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class EncodeJSON block\n    class Source hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute EncodeJSON\n```\n\n#### [`Hash`]\n\nA block that computes the cryptographic hash of a byte stream, while optionally\npassing it through.\n\n```mermaid\nblock-beta\n    columns 7\n    Source space:2 Hash space:2 Sink\n    space:7\n    space:7\n    space:3 Result space:3\n    Source-- \"input\" --\u003eHash\n    Hash-- \"output\" --\u003eSink\n    Hash-- \"hash\" --\u003eResult\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class Hash block\n    class Source hidden\n    class Sink hidden\n    class Result hidden\n```\n\n```bash\nprotoflow execute Hash algorithm=blake3\n```\n\n#### [`Random`]\n\nA block for generating and sending a random value.\n\n```mermaid\nblock-beta\n    columns 4\n    Random space:2 Sink\n    Random-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class Random block\n    class Sink hidden\n```\n\n```bash\nprotoflow execute Random seed=42\n```\n\n#### [`ReadDir`]\n\nA block that reads file names from a file system directory.\n\n```mermaid\nblock-beta\n    columns 4\n    Config space:3\n    space:4\n    space:4\n    ReadDir space:2 Sink\n    Config-- \"path\" --\u003eReadDir\n    ReadDir-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class ReadDir block\n    class Config hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute ReadDir path=/tmp\n```\n\n#### [`ReadEnv`]\n\nA block that reads the value of an environment variable.\n\n```mermaid\nblock-beta\n    columns 4\n    Config space:3\n    space:4\n    space:4\n    ReadEnv space:2 Sink\n    Config-- \"name\" --\u003eReadEnv\n    ReadEnv-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class ReadEnv block\n    class Config hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute ReadEnv name=TERM\n```\n\n#### [`ReadFile`]\n\nA block that reads bytes from the contents of a file.\n\n```mermaid\nblock-beta\n    columns 4\n    Config space:3\n    space:4\n    space:4\n    ReadFile space:2 Sink\n    Config-- \"path\" --\u003eReadFile\n    ReadFile-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class ReadFile block\n    class Config hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute ReadFile path=/tmp/file.txt\n```\n\n#### [`ReadSocket`]\n\nA block that reads bytes from a TCP socket.\n\n```mermaid\nblock-beta\n    columns 4\n    ReadSocket space:2 Sink\n    ReadSocket-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class ReadSocket block\n    class Sink hidden\n```\n\n```bash\nprotoflow execute ReadSocket connection=tcp://127.0.0.1:7077 buffer_size=1024\n```\n\n#### [`ReadStdin`]\n\nA block that reads bytes from standard input (aka stdin).\n\n```mermaid\nblock-beta\n    columns 4\n    ReadStdin space:2 Sink\n    ReadStdin-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class ReadStdin block\n    class Sink hidden\n```\n\n```bash\nprotoflow execute ReadStdin \u003c input.txt\n```\n\n#### [`SplitString`]\n\nA block that splits the received input message, with an optional delimiter string parameter\n\n```mermaid\nblock-beta\n    columns 7\n    Source space:2 SplitString space:2 Sink\n    Source-- \"input\" --\u003eSplitString\n    SplitString-- \"output\" --\u003eSink\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class SplitString block\n    class Source hidden\n    class Sink hidden\n```\n\n```bash\nprotoflow execute SplitString delimiter=\",\"\n```\n\n#### [`WriteFile`]\n\nA block that writes or appends bytes to the contents of a file.\n\n```mermaid\nblock-beta\n    columns 4\n    space:3 Config\n    space:4\n    space:4\n    Source space:2 WriteFile\n    Config-- \"path\" --\u003eWriteFile\n    Source-- \"input\" --\u003eWriteFile\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class WriteFile block\n    class Config hidden\n    class Source hidden\n```\n\n```bash\nprotoflow execute WriteFile path=/tmp/file.txt\n```\n\n#### [`WriteSocket`]\n\nA block that writes bytes to TCP socket.\n\n```mermaid\nblock-beta\n    columns 4\n    Source space:2 WriteSocket\n    Source-- \"input\" --\u003eWriteSocket\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class WriteSocket block\n    class Source hidden\n```\n\n```bash\nprotoflow execute WriteSocket connection=tcp://127.0.0.1:7077 buffer_size=1024\n```\n\n#### [`WriteStderr`]\n\nA block that writes bytes to standard error (aka stderr).\n\n```mermaid\nblock-beta\n    columns 4\n    Source space:2 WriteStderr\n    Source-- \"input\" --\u003eWriteStderr\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class WriteStderr block\n    class Source hidden\n```\n\n```bash\nprotoflow execute WriteStderr \u003c input.txt 2\u003e output.txt\n```\n\n#### [`WriteStdout`]\n\nA block that writes bytes to standard output (aka stdout).\n\n```mermaid\nblock-beta\n    columns 4\n    Source space:2 WriteStdout\n    Source-- \"input\" --\u003eWriteStdout\n\n    classDef block height:48px,padding:8px;\n    classDef hidden visibility:none;\n    class WriteStdout block\n    class Source hidden\n```\n\n```bash\nprotoflow execute WriteStdout \u003c input.txt \u003e output.txt\n```\n\n## 👨‍💻 Development\n\n```bash\ngit clone https://github.com/asimov-platform/protoflow.git\n```\n\n### Guidelines\n\n#### Contributing a pull request\n\n- Do your best to adhere to the existing coding conventions and idioms.\n- Make sure to run `cargo fmt` prior to submitting your pull request.\n- Don't leave trailing whitespace on any line, and make sure all text files\n  include a terminating newline character.\n\n#### Adding a new block type\n\nTo add a new block type implementation, make sure to examine and amend:\n\n- The block type reference (table and subsections) in this README.\n- The appropriate subdirectory under [`lib/protoflow-blocks/src/blocks/`],\n  such as `core`, `flow`, `hash`, `io`, `math`, `sys`, or `text`.\n- The `BlockTag` enum in [`lib/protoflow-blocks/src/block_tag.rs`],\n  which lists the names of all available block types.\n- The `BlockConfig` enum in [`lib/protoflow-blocks/src/block_config.rs`],\n  which implements block instantiation and Serde deserialization.\n- The system-building DSL in [`lib/protoflow-blocks/src/system.rs`],\n  which provides convenience builder methods for system definition.\n- The `build_stdio_system()` function in [`lib/protoflow-blocks/src/lib.rs`],\n  which is used by the CLI to instantiate blocks for standard I/O.\n- The documented block diagrams and sequence diagrams under\n  [`lib/protoflow-blocks/doc/`], which are embedded in the README and docs.\n\n\u003e [!NOTE]\n\u003e If a block implementation requires additional crate dependencies, it may\n\u003e be appropriate for that block availability to be featured-gated so as to\n\u003e enable developers to opt out of those dependencies.\n\n#### Block implementation notes\n\n- Blocks must not panic; use other error-handling strategies. Ideally, block\n  implementations should be robust and infallible. When that's not possible,\n  consider encoding errors by having the output message type be an enum (cf.\n  Rust's `Result`) or consider having a dedicated error output port. If truly\n  necessary, abort block execution by returning a `BlockError`.\n- Blocks should not generally spawn threads.\n- Blocks should document their system resource requirements, if any.\n- Blocks should use the [`tracing`] crate for logging any errors, warnings,\n  and debug output. However, since tracing is an optional feature and\n  dependency, do make sure to feature-gate any use of tracing behind a\n  `#[cfg(feature = \"tracing\")]` guard.\n\n- - -\n\n[![Share on Twitter](https://img.shields.io/badge/share%20on-twitter-03A9F4?logo=twitter)](https://twitter.com/share?url=https://github.com/asimov-platform/protoflow\u0026text=Protoflow)\n[![Share on Reddit](https://img.shields.io/badge/share%20on-reddit-red?logo=reddit)](https://reddit.com/submit?url=https://github.com/asimov-platform/protoflow\u0026title=Protoflow)\n[![Share on Hacker News](https://img.shields.io/badge/share%20on-hacker%20news-orange?logo=ycombinator)](https://news.ycombinator.com/submitlink?u=https://github.com/asimov-platform/protoflow\u0026t=Protoflow)\n[![Share on Facebook](https://img.shields.io/badge/share%20on-facebook-1976D2?logo=facebook)](https://www.facebook.com/sharer/sharer.php?u=https://github.com/asimov-platform/protoflow)\n\n[Protocol Buffers]: https://protobuf.dev\n[Rust]: https://rust-lang.org\n[flow-based programming]: https://jpaulm.github.io/fbp/\n[naming conventions]: https://rust-lang.github.io/api-guidelines/naming.html\n[`tracing`]: https://crates.io/crates/tracing\n\n[`count_lines`]: lib/protoflow/examples/count_lines\n[`echo_lines`]: lib/protoflow/examples/echo_lines\n[`examples`]: lib/protoflow/examples\n\n[`Buffer`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.Buffer.html\n[`ConcatStrings`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.ConcatStrings.html\n[`Const`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.Const.html\n[`Count`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.Count.html\n[`Decode`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.Decode.html\n[`DecodeCSV`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.DecodeCsv.html\n[`DecodeHex`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.DecodeHex.html\n[`DecodeJSON`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.DecodeJson.html\n[`Delay`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.Delay.html\n[`Drop`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.Drop.html\n[`Encode`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.Encode.html\n[`EncodeCSV`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.EncodeCsv.html\n[`EncodeHex`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.EncodeHex.html\n[`EncodeJSON`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.EncodeJson.html\n[`Hash`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.Hash.html\n[`Random`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.Random.html\n[`ReadDir`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.ReadDir.html\n[`ReadEnv`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.ReadEnv.html\n[`ReadFile`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.ReadFile.html\n[`ReadSocket`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.ReadSocket.html\n[`ReadStdin`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.ReadStdin.html\n[`SplitString`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.SplitString.html\n[`WriteFile`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.WriteFile.html\n[`WriteSocket`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.WriteSocket.html\n[`WriteStderr`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.WriteStderr.html\n[`WriteStdout`]: https://docs.rs/protoflow-blocks/latest/protoflow_blocks/struct.WriteStdout.html\n\n[`lib/protoflow-blocks/doc/`]: https://github.com/asimov-platform/protoflow/tree/master/lib/protoflow-blocks/doc\n[`lib/protoflow-blocks/src/blocks/`]: https://github.com/asimov-platform/protoflow/tree/master/lib/protoflow-blocks/src/blocks\n[`lib/protoflow-blocks/src/lib.rs`]: https://github.com/asimov-platform/protoflow/blob/master/lib/protoflow-blocks/src/lib.rs\n[`lib/protoflow-blocks/src/block_config.rs`]: https://github.com/asimov-platform/protoflow/blob/master/lib/protoflow-blocks/src/block_config.rs\n[`lib/protoflow-blocks/src/block_tag.rs`]: https://github.com/asimov-platform/protoflow/blob/master/lib/protoflow-blocks/src/block_tag.rs\n[`lib/protoflow-blocks/src/system.rs`]: https://github.com/asimov-platform/protoflow/blob/master/lib/protoflow-blocks/src/system.rs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasimov-platform%2Fprotoflow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fasimov-platform%2Fprotoflow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fasimov-platform%2Fprotoflow/lists"}