Appliance

Cargo minimum rustc 1.49

Overview

Appliance is a lightweight Rust framework for building highly customizable asynchronous components adapted for message-based intercommunications. This project is an attempt to simplify actix-like approach exempting a user from using predefined execution runtimes. With the library you can design any composition logic for async agents avoiding data races and unnecessary locks.

A quick ping-pong example

```rust use appliance::Appliance; use std::{ sync::{Arc, Weak}, thread, time::Duration, };

type PingAppliance = Appliance; type PongAppliance = Appliance;

enum PingMessage { RegisterPong(Weak), Send(i16), }

struct PingState { pong: Weak, }

impl Drop for PingState { fn drop(&mut self) { println!("dropping PingState"); } }

fn pinghandler(state: &mut PingState, message: PingMessage) { match message { PingMessage::RegisterPong(pong) => state.pong = pong, PingMessage::Send(c) => { if let Some(pong) = &state.pong.upgrade() { println!("ping received {}", c); let _ = pong.handle(PongMessage::Send(c + 1)); thread::sleep(Duration::fromsecs(1)); } } } }

enum PongMessage { RegisterPing(Weak), Send(i16), }

struct PongState { ping: Weak, }

impl Drop for PongState { fn drop(&mut self) { println!("dropping PongState"); } }

fn ponghandler(state: &mut PongState, message: PongMessage) { match message { PongMessage::RegisterPing(ping) => state.ping = ping, PongMessage::Send(c) => { if let Some(ping) = &state.ping.upgrade() { println!("pong received {}", c); let _ = ping.handle(PingMessage::Send(c + 1)); thread::sleep(Duration::fromsecs(1)); } } } }

fn main() { let executor = &appliance::DEFAULTEXECUTOR; // Create ping appliance. let pingstate = PingState { pong: Default::default(), }; let ping = Arc::new(Appliance::new(executor, pingstate, pinghandler, None)); // Create pong appliance. let pongstate = PongState { ping: Default::default(), }; let pong = Arc::new(Appliance::new(executor, pongstate, ponghandler, None)); let _ = ping.handle(PingMessage::RegisterPong(Arc::downgrade(&pong))); let _ = pong.handle(PongMessage::RegisterPing(Arc::downgrade(&ping))); // Ignite ping-pong. let _ = ping.handle(PingMessage::Send(0)); thread::sleep(Duration::fromsecs(5)); drop(ping); drop(pong); thread::sleep(Duration::from_secs(1)); } ```

Installation

The recommended way to use this library is to add it as a dependency in your Cargo.toml file:

[dependencies] appliance = "0.1.1"