| Crates.io | plug |
| lib.rs | plug |
| version | 0.1.0-dev.1 |
| created_at | 2025-07-23 18:39:51.599689+00 |
| updated_at | 2025-09-15 05:32:58.927895+00 |
| description | A library for type-safe interprocess communication |
| homepage | |
| repository | https://github.com/hecrj/plug |
| max_upload_size | |
| id | 1765132 |
| size | 26,005 |
Define the input and output of a wired connection:
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub struct Credentials {
username: String,
password: String,
}
#[derive(Serialize, Deserialize)]
pub enum Authentication {
Success { token: String },
Error { description: String },
}
Create a Plug for this specific action:
use plug::Plug;
pub const LOG_IN: Plug<Credentials, Authentication> = Plug::new("log_in");
Connect the Plug to the server leveraging type-safety:
use std::io;
async fn log_in(credentials: Credentials) -> io::Result<Authentication> {
let mut connection = LOG_IN.connect("127.0.0.1:1234").await?;
connection.write(credentials).await?;
connection.read().await
}
Implement the server by gathering all the Plug definitions in a Strip:
use plug::{Connection, Strip};
use std::io;
use tokio::net;
use tokio::task;
async fn run_server() -> io::Result<()> {
let strip = Strip::new().plug(LOG_IN, log_in);
let server = net::TcpListener::bind("127.0.0.1:1234").await?;
loop {
let Ok((client, _address)) = server.accept().await else {
continue;
};
let _ = strip.attach(client).await;
}
}
async fn log_in(mut connection: Connection<Authentication, Credentials>) -> io::Result<()> {
let credentials = connection.read().await?;
let result = if credentials.username == "admin" && credentials.password == "1234" {
Authentication::Success { token: "verysecure".to_owned() }
} else {
Authentication::Error { description: "Invalid credentials!".to_owned() }
};
connection.write(result).await
}