# Protoflow
[](https://unlicense.org)
[](https://rust-lang.org)
[](https://crates.io/crates/protoflow)
🚧 _This is presently under heavy construction._
## 🛠️ Prerequisites
- [Rust](https://rust-lang.org) 1.70+
## ⬇️ Installation
### Installation via Cargo
```console
$ cargo add protoflow
```
## 👉 Examples
### Importing the library
```rust
use protoflow::*;
```
### Authoring a simple DROP block
```rust
use protoflow::{Block, BlockError, InputPort, Message, PortDescriptor, Scheduler};
use protoflow::derive::Block;
/// A block that simply discards all messages it receives.
#[derive(Block)]
pub struct Drop<T: Message>(#[input] InputPort<T>);
impl<T: Message> Block for Drop<T> {
fn execute(&mut self, _scheduler: &dyn Scheduler) -> Result<(), BlockError> {
while let Some(message) = self.0.receive()? {
drop(message);
}
Ok(())
}
}
```
### Authoring a simple DELAY block
```rust
use protoflow::{Block, BlockError, InputPort, Message, OutputPort, Port, PortDescriptor, Scheduler};
use protoflow::derive::Block;
use std::time::Duration;
/// A block that passes messages through while delaying them by a fixed
/// duration.
#[derive(Block)]
pub struct Delay<T: Message> {
/// The input message stream.
#[input]
input: InputPort<T>,
/// The output target for the stream being passed through.
#[output]
output: OutputPort<T>,
/// A configuration parameter for how much delay to add.
#[parameter]
delay: Duration,
}
impl<T: Message> Block for Delay<T> {
fn execute(&mut self, scheduler: &dyn Scheduler) -> Result<(), BlockError> {
while let Some(message) = self.input.receive()? {
scheduler.sleep_for(self.delay)?;
if self.output.is_connected() {
self.output.send(&message)?;
}
}
Ok(())
}
}
```
### Authoring a trivial function block
```rust
use protoflow::{BlockError, FunctionBlock, InputPort, OutputPort};
use protoflow::derive::FunctionBlock;
/// A block that simply echoes inputs to outputs.
#[derive(FunctionBlock)]
pub struct Echo(InputPort<i64>, OutputPort<i64>);
impl FunctionBlock<i64, i64> for Echo {
fn compute(&self, input: i64) -> Result<i64, BlockError> {
Ok(input)
}
}
```
## 📚 Reference
### Features
- [`flume`](lib/protoflow/Cargo.toml)
- [`rand`](lib/protoflow/Cargo.toml)
- [`std`](lib/protoflow/Cargo.toml)
- [`tokio`](lib/protoflow/Cargo.toml)
- [`tracing`](lib/protoflow/Cargo.toml)
- [`web`](lib/protoflow/Cargo.toml)
- [`zeromq`](lib/protoflow/Cargo.toml)
### Runtimes
- [`runtimes::StdThread`](lib/protoflow/src/runtimes/std_thread.rs)
- [`runtimes::Tokio`](lib/protoflow/src/runtimes/tokio.rs)
- [`runtimes::Web`](lib/protoflow/src/runtimes/web.rs)
### Transports
- [`transports::Flume`](lib/protoflow/src/transports/flume.rs)
- [`transports::ZeroMQ`](lib/protoflow/src/transports/zeromq.rs)
### Blocks
TODO
## 👨💻 Development
```console
$ git clone https://github.com/artob/protoflow.git
```
- - -
[](https://twitter.com/share?url=https://github.com/artob/protoflow&text=Protoflow)
[](https://reddit.com/submit?url=https://github.com/artob/protoflow&title=Protoflow)
[](https://news.ycombinator.com/submitlink?u=https://github.com/artob/protoflow&t=Protoflow)
[](https://www.facebook.com/sharer/sharer.php?u=https://github.com/artob/protoflow)