Struct orx_closure::Capture
source · pub struct Capture<Data>(pub Data);Expand description
A utility wrapper which simply wraps around data to be captured and allows methods to define desired closures.
Closures defined in this crate are built by
Capture(data)which does nothing but captures thedata,- followed by:
fun(fn)to create aClosurefun_ref(fn)to create aClosureReffun_option_ref(fn)to create aClosureOptReffun_result_ref(fn)to create aClosureResRef
where fn is a non-capturing anonymous function of the correct signature.
All these methods are consuming moving the data into the corresponding closure.
The desired way to capture the data is decided by the caller:
Capture(data)moves the data into the capture, and eventually to the closure,Capture(&data)only captures a reference to thedata,Capture(data.clone())moves a clone of thedata, etc.
Important note related to how we capture and closure variants:
-
Closurecreated by thefunis sufficient for all types:- when we capture by reference, and/or
- when we return a value, rather than a reference.
-
To deal with lifetime errors, we need:
ClosureRefcreated byfun_refwhen we capture the ownership of the data and return a reference,ClosureOptRefcreated byfun_option_refwhen we capture the ownership of the data and return anOptionof a reference,ClosureResRefcreated byfun_result_refwhen we capture the ownership of the data and return aResultof a reference.
Examples
use orx_closure::*;
use std::rc::Rc;
let numbers = vec![42];
// fun is sufficient in all cases when the data is captured by reference
let fun = Capture(&numbers).fun(|vec, i| vec[i]);
assert_eq!(42, fun.call(0));
let fun = Capture(&numbers).fun(|vec, i| &vec[i]);
assert_eq!(&42, fun.call(0));
let fun = Capture(&numbers).fun(|vec, i| vec.get(i));
assert_eq!(Some(&42), fun.call(0));
let fun = Capture(&numbers).fun(|vec, i| vec.get(i).ok_or("no-data"));
assert_eq!(Ok(&42), fun.call(0));
// we need the other variants
let fun = Capture(numbers.clone()).fun_ref(|vec, i| &vec[i]);
assert_eq!(&42, fun.call(0));
let fun = Capture(Rc::new(numbers.clone())).fun_option_ref(|vec, i| vec.get(i));
assert_eq!(Some(&42), fun.call(0));
let fun = Capture(numbers).fun_result_ref(|vec, i| vec.get(i).ok_or("no-data"));
assert_eq!(Ok(&42), fun.call(0));Tuple Fields§
§0: DataImplementations§
source§impl<Data> Capture<Data>
impl<Data> Capture<Data>
sourcepub fn fun<In, Out>(
self,
fun: fn(_: &Data, _: In) -> Out
) -> Closure<Data, In, Out>
pub fn fun<In, Out>( self, fun: fn(_: &Data, _: In) -> Out ) -> Closure<Data, In, Out>
Defines a Closure<Data, In, Out> capturing Data and defining In -> Out transformation.
Consumes the Capture and moves the captured data inside the created closure.
Example
use orx_closure::Capture;
let base = 2;
let modulo = Capture(base).fun(|b, n| n % b);
assert_eq!(0, modulo.call(42));
assert_eq!(1, modulo.call(7));sourcepub fn fun_ref<In, Out: ?Sized>(
self,
fun: fn(_: &Data, _: In) -> &Out
) -> ClosureRef<Data, In, Out>
pub fn fun_ref<In, Out: ?Sized>( self, fun: fn(_: &Data, _: In) -> &Out ) -> ClosureRef<Data, In, Out>
Defines a ClosureRef<Data, In, Out> capturing Data and defining In -> &Out transformation.
Consumes the Capture and moves the captured data inside the created closure.
Note tha twe only need this closure variant when:
- the data is captured by ownership rather than as a reference, and
- we want to return a reference.
Example
use orx_closure::Capture;
struct Person { name: String }
let people = [Person { name: "john".to_string() }, Person { name: "doe".to_string() }];
// name_of_person_with_id: ClosureRef<[Person; 2], usize, str>
let name_of_person_with_id =
Capture(people).fun_ref(|ppl, id: usize| ppl[id].name.as_str());
assert_eq!("john", name_of_person_with_id.call(0));sourcepub fn fun_option_ref<In, Out: ?Sized>(
self,
fun: fn(_: &Data, _: In) -> Option<&Out>
) -> ClosureOptRef<Data, In, Out>
pub fn fun_option_ref<In, Out: ?Sized>( self, fun: fn(_: &Data, _: In) -> Option<&Out> ) -> ClosureOptRef<Data, In, Out>
Defines a ClosureOptRef<Data, In, Out> capturing Data and defining In -> Option<&Out> transformation.
Consumes the Capture and moves the captured data inside the created closure.
Note tha twe only need this closure variant when:
- the data is captured by ownership rather than as a reference, and
- we want to return an
Optionof a reference.
Example
use orx_closure::Capture;
struct Person { name: String }
let people = [Person { name: "john".to_string() }, Person { name: "doe".to_string() }];
// name_of_person_with_id: ClosureOptRef<[Person; 2], usize, str>
let name_of_person_with_id =
Capture(people).fun_option_ref(|ppl, id: usize| ppl.get(id).map(|p| p.name.as_str()));
assert_eq!(Some("john"), name_of_person_with_id.call(0));
assert_eq!(None, name_of_person_with_id.call(42));
// alternatively
let fun = name_of_person_with_id.as_fn();
assert_eq!(Some("doe"), fun(1));sourcepub fn fun_result_ref<In, Out: ?Sized, Error>(
self,
fun: fn(_: &Data, _: In) -> Result<&Out, Error>
) -> ClosureResRef<Data, In, Out, Error>
pub fn fun_result_ref<In, Out: ?Sized, Error>( self, fun: fn(_: &Data, _: In) -> Result<&Out, Error> ) -> ClosureResRef<Data, In, Out, Error>
Defines a ClosureResRef<Data, In, Out, Error> capturing Data and defining In -> Result<&Out, Error> transformation.
Consumes the Capture and moves the captured data inside the created closure.
Note tha twe only need this closure variant when:
- the data is captured by ownership rather than as a reference, and
- we want to return a
Resultof a reference.
Example
use orx_closure::Capture;
struct Person { name: String }
let people = [Person { name: "john".to_string() }, Person { name: "doe".to_string() }];
// name_of_person_with_id: ClosureResRef<[Person; 2], usize, str, String>
let name_of_person_with_id = Capture(people).fun_result_ref(|ppl, id: usize| {
ppl.get(id)
.map(|p| p.name.as_str())
.ok_or_else(|| "unknown id".to_string())
});
assert_eq!(Ok("john"), name_of_person_with_id.call(0));
assert_eq!(Err("unknown id".to_string()), name_of_person_with_id.call(42));sourcepub fn into_captured_data(self) -> Data
pub fn into_captured_data(self) -> Data
Consumes the Capture and returns back the captured data.
Example
use orx_closure::*;
let data = vec![42];
let capture = Capture(data);
let data_back = capture.into_captured_data();
assert_eq!(vec![42], data_back);