| Crates.io | sans |
| lib.rs | sans |
| version | 0.1.0-alpha.4 |
| created_at | 2025-10-09 04:38:36.667474+00 |
| updated_at | 2025-10-13 18:44:02.50212+00 |
| description | Composable coroutine-based programming library for sans-io |
| homepage | |
| repository | https://github.com/yiblet/sans |
| max_upload_size | |
| id | 1875030 |
| size | 199,038 |
sans is a coroutine combinators library for building composable, resumable computations in Rust. Build pipelines that yield, resume, and compose beautifully.
What are coroutine combinators? Instead of writing complex state machines with explicit state tracking, you compose small, focused functions into pipelines. Each coroutine can yield intermediate results, maintain state, and pass control to the next coroutine. The result is code that's easier to write, test, and reuse - all with compile-time type safety and zero-cost abstractions.
Interactive calculator that maintains state across inputs:
use sans::prelude::*;
// Build a stateful calculator that accumulates results
let mut total = 0_i64;
let calculator = init_repeat(0_i64, move |delta: i64| {
total += delta;
total
})
.map_input(|cmd: &str| -> i64 {
let mut parts = cmd.split_whitespace();
let op = parts.next().expect("operation");
let amount: i64 = parts.next().expect("amount").parse().expect("number");
match op {
"add" => amount,
"sub" => -amount,
_ => panic!("unknown operation"),
}
})
.map_yield(|value: i64| format!("total={}", value));
// Execute the pipeline
let (initial, mut coro) = calculator.init().unwrap_yielded();
println!("{}", initial); // "total=0"
println!("{}", coro.next("add 5").unwrap_yielded()); // "total=5"
println!("{}", coro.next("sub 3").unwrap_yielded()); // "total=2"
println!("{}", coro.next("add 10").unwrap_yielded()); // "total=12"
Chained pipeline with transformation:
use sans::prelude::*;
let pipeline = init_once(10, |x: i32| x * 2)
.map_yield(|x| x + 5)
.chain(once(|x: i32| x * 3))
.map_return(|x| format!("Result: {}", x));
let result = handle(pipeline, |output| {
println!("Step: {}", output);
output // Pass through
});
println!("{}", result); // "Result: 45"
Build stateful, resumable pipelines for:
Key benefits:
#![forbid(unsafe_code)], no manual state management bugsjoinAdd to your Cargo.toml:
[dependencies]
sans = "0.1.0-alpha.2"
use sans::prelude::*;
Requirements: Rust 1.85+
Full API Documentation - Complete reference for all types, traits, and functions
Key modules:
sans::build - Create coroutines (once, repeat, init_once)sans::compose - Combine coroutines (chain, map_input, map_yield)sans::concurrent - Concurrent execution (join, poll)sans::run - Execute pipelines (handle, handle_async)License: See LICENSE | Contributing: TBD