hackfn

Crates.iohackfn
lib.rshackfn
version0.1.8
sourcesrc
created_at2018-09-08 08:08:55.054082
updated_at2022-12-18 21:26:13.627311
descriptionFake implementation of `std::ops::Fn` for user-defined data types.
homepage
repositoryhttps://github.com/dtolnay/hackfn
max_upload_size
id83583
size26,233
Lanthanum (github:zxtn:lanthanum)

documentation

https://docs.rs/hackfn

README

#[hackfn]

github crates.io docs.rs build status

Fake implementation of std::ops::Fn for user-defined data types.

Place a #[hackfn] attribute on an impl block containing a single method to use that method as the implementation of the function call operator.

[dependencies]
hackfn = "0.1"

Version requirement: #[hackfn] supports rustc 1.31+

Limitations

  • The function must receive &self. Functions that receive &mut self or self are not supported.

  • The function may not have generic parameters or where-clause.

  • The Self type must implement Sized.

Examples

use hackfn::hackfn;

/// Function object that adds some number to its input.
struct Plus(u32);

#[hackfn]
impl Plus {
    fn call(&self, other: u32) -> u32 {
        self.0 + other
    }
}

fn main() {
    let plus_one = Plus(1);
    let sum = plus_one(2);
    assert_eq!(sum, 3);
}

The next example is somewhat more elaborate:

  • Interior mutability can be used to approximate a FnMut impl.

  • Generic parameters and where-clause are permitted on the impl block (though not on the function).

  • The function may take any number of arguments.

use hackfn::hackfn;

use std::cell::Cell;
use std::ops::Add;

/// Function object that accumulates a pair of values per call.
#[derive(Default)]
struct AccumulatePairs<T> {
    first: Cell<T>,
    second: Cell<T>,
}

#[hackfn]
impl<T> AccumulatePairs<T> where T: Copy + Add<Output = T> {
    fn call(&self, first: T, second: T) {
        self.first.set(self.first.get() + first);
        self.second.set(self.second.get() + second);
    }
}

fn main() {
    let accumulate = AccumulatePairs::default();
    accumulate(30, 1);
    accumulate(20, 2);
    accumulate(10, 3);
    assert_eq!(accumulate.first.get(), 60);
    assert_eq!(accumulate.second.get(), 6);
}

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Commit count: 65

cargo fmt