box_closure

Crates.iobox_closure
lib.rsbox_closure
version0.1.0
created_at2025-08-13 22:44:41.406229+00
updated_at2025-08-13 22:44:41.406229+00
descriptionSimple closure wrappers with no dependencies
homepage
repositoryhttps://github.com/bobbothe2nd/box_closure
max_upload_size
id1794218
size18,438
bobbothe2nd (bobbothe2nd)

documentation

https://docs.rs/box_closure

README

box_closure

box_closure provides opaque wrappers over Rust closures (Fn, FnMut, FnOnce) for no-alloc environments.

Rust treats closures as unique types, even when their behavior is identical. This can cause compiler errors when passing closures in generic contexts. Normally, Box<dyn Fn> solves this by heap-allocating the closure, but heap allocation isn’t always available—especially in embedded systems.

box_closure offers OpaqueFn, OpaqueFnMut, and OpaqueFnOnce:

  • Hide the concrete type of the closure from the compiler.
  • Allow stack-only storage in a fixed-size, aligned buffer.
  • Provide safe dispatch without heap allocation.
  • Prevent opaque type mismatch compiler errors.

Closure Wrappers

Type Semantics Use case
OpaqueFn Immutable closure (Fn) Shared access, stateless or read-only captures
OpaqueFnMut Mutable closure (FnMut) Closures that mutate captured state
OpaqueFnOnce Single-use closure (FnOnce) Closures that consume captured state

Quick Reference

Closures

OpaqueFn

use box_closure::{OpaqueFn, Align8};

let y = 10;
let f = OpaqueFn::<_, u32, Align8<32>>::new(|x: u32| x + y);
assert_eq!(f.call(5), 15);

OpaqueFnMut

use box_closure::{OpaqueFnMut, Align8};
use core::cell::Cell;

let counter = Cell::new(0);
let f = OpaqueFnMut::<_, (), Align8<32>>::new(move |_| {
    counter.set(counter.get() + 1);
});

f.call(());
f.call(());
assert_eq!(counter.get(), 2);

OpaqueFnOnce

use box_closure::{OpaqueFnOnce, Align16};

let s = String::from("hello");
let f = OpaqueFnOnce::<_, usize, Align16<64>>::new(move |x: usize| {
    x + s.len()
});

assert_eq!(f.call(5), 10); // consumes closure

Buffer Alignment

Buffer Type Alignment Typical Size
Align1<N> 1 byte N bytes
Align2<N> 2 bytes N bytes
Align4<N> 4 bytes N bytes
Align8<N> 8 bytes N bytes
Align16<N> 16 bytes N bytes
Align32<N> 32 bytes N bytes
Align64<N> 64 bytes N bytes

Benefits

  • No heap allocation: everything fits in a fixed buffer.
  • Opaque types prevent generic mismatch errors.
  • Safe consumption of FnOnce closures without double drop.
  • Designed for embedded and no-alloc environments.
Commit count: 0

cargo fmt