box_closure 0.1.0

Simple closure wrappers with no dependencies
Documentation
  • Coverage
  • 100%
    11 out of 11 items documented0 out of 0 items with examples
  • Size
  • Source code size: 17.92 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 2.88 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 13s Average build duration of successful builds.
  • all releases: 13s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • bobbothe2nd/box_closure
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • bobbothe2nd

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.