TinyFn crate

crates docs actions MIT/Apache loc

Motivation

Did you ever boxed closure and wondered: "Is there a crate to avoid heap allocations for small closures?"

Well, wonder no more, this is the crate.

How to use

This crate provides declarative macro [tiny_fn!] which generates closure wrappers to store closures without original closure type. Generated closure wrappers avoid heap allocations when wrapped closure fits inline storage.

The macro is designed to be easy to write with simple syntax that mostly reuse constructs existing in Rust. Behavior of generated wrappers should be obvious from the first glance.

Example

rust tiny_fn! { struct Foo = Fn(a: i32, b: i32) -> i32; }

Macro expands to struct Foo definition with two public methods.

[tiny_fn!] macro supports defining multiple items at once.

rust tiny_fn! { struct Foo = Fn(a: i32, b: i32) -> i32; struct Bar = Fn() -> String; }

Visibility

[tiny_fn!] macro supports visibility qualifiers.

rust tiny_fn! { pub struct Foo = Fn(a: i32, b: i32) -> i32; struct Bar = Fn() -> String; pub(crate) struct Baz = Fn(); }

Attributes

[tiny_fn!] macro supports item attributes, including documentation.

rust tiny_fn! { /// This is `Foo` wrapper for that takes two `i32`s and return `i32`. pub struct Foo = Fn(a: i32, b: i32) -> i32; }

Fn* traits family

[tiny_fn!] macro can generate closure wrappers for any of the Fn* traits family.

rust tiny_fn! { struct A = Fn(); struct B = FnMut(); struct C = FnOnce(); }

Generics

Closure wrappers can be declared generic over number of types and those types should be used in function signature.

rust tiny_fn! { struct BinOp<T> = Fn(a: T, b: T) -> T; }

Here BinOp is generic over T.\ BiOp::<T>::new accepts closures bounds by Fn(T, T) -> T.

Notably T is not constrained by traits in BinOp.\ Closure wrappers only move arguments and return values, so they don't need to know anything else about the type.

Special generic parameters

Closure wrapper generated by [tiny_fn!] macro always have two generic parameters besides generic types specified by macro caller: * Lifetime 'closure.\ Wrapper contains closures bound by 'closure lifetime. * Constant INLINE_SIZE: usize.\ Closures with size up to INLINE_SIZE and alignment requirement not exceeding [tiny_fn::ALIGN] will be inlined into wrapper structure directly.\ Otherwise heap allocation will occur.\ INLINE_SIZE parameter is defaulted to tiny_fn::DEFAULT_INLINE_SIZE which is 24 currently.

License

Licensed under either of

at your option.

Contributions

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.