pub struct ClosureOptRef<Capture, In, Out: ?Sized> { /* private fields */ }
Expand description

Closure strictly separating the captured data from the function, and hence, having two components:

  • Capture is any captured data,
  • fn(&Capture, In) -> Option<&Out> is the transformation.

It represents the transformation In -> Option<&Out>.

Note that, unlike trait objects of fn-traits, Capture auto-implements Clone given that captured data is cloneable.

Instead of ClosureOptRef; this closure variant is particularly useful when we capture the data by value and return an Option of 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));

Implementations§

source§

impl<Capture, In, Out: ?Sized> ClosureOptRef<Capture, In, Out>

source

pub fn call(&self, input: In) -> Option<&Out>

Calls the closure with the given input.

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));
source

pub fn captured_data(&self) -> &Capture

Returns a reference to the captured data.

source

pub fn into_captured_data(self) -> Capture

Consumes the closure and returns back the captured data.

Example
use orx_closure::Capture;

struct ExpensiveData(Vec<i32>);

let data = ExpensiveData(vec![10, 11, 12]);

let get_number = Capture(data).fun_option_ref(|data, i| data.0.get(i));

assert_eq!(Some(&10), get_number.call(0));
assert_eq!(Some(&12), get_number.call(2));

let _data: ExpensiveData = get_number.into_captured_data();
source

pub fn as_fn<'a>(&'a self) -> impl Fn(In) -> Option<&'a Out>

Returns the closure as an impl Fn(In) -> Option<&Out> struct, allowing the convenience

  • to avoid the call method,
  • or pass the closure to functions accepting a function generic over the Fn.
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()));

// alternatively
let fun = name_of_person_with_id.as_fn();
assert_eq!(Some("doe"), fun(1));
source§

impl<Capture, In, Out: ?Sized> ClosureOptRef<Capture, In, Out>

source

pub fn into_oneof2_var1<Var2>( self ) -> ClosureOptRefOneOf2<Capture, Var2, In, Out>

Transforms ClosureOptRef<C1, In, Out> into the more general ClosureRefOneOf2<C1, C2, In, Out> for any C2.

Example
use orx_closure::*;

type Toy = String;
struct Cat {
    name: String,
    favorite_toys: Vec<Toy>,
}
struct Dog {
    name: String,
    nickname: String,
    favorite_toys: Vec<Toy>,
}

struct PresentIdeas<'a> {
    // for cats or dogs
    for_pet: ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &'a str, [Toy]>,
}

// cats
let cats = vec![Cat {
    name: "bella".to_string(),
    favorite_toys: vec!["ball".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(cats)
        .fun_option_ref(|cats, name| {
            cats.iter()
                .find(|cat| cat.name == name)
                .map(|cat| cat.favorite_toys.as_slice())
        })
        // transforms        : ClosureOptRef<Vec<Cat>, &str, [Toy]>
        // into more general : ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &str, [Toy]>
        .into_oneof2_var1(),
};

assert_eq!(
    Some(vec!["ball".to_string()].as_slice()),
    present_ideas.for_pet.call("bella")
);
assert!(present_ideas.for_pet.call("luna").is_none());
source

pub fn into_oneof2_var2<Var1>( self ) -> ClosureOptRefOneOf2<Var1, Capture, In, Out>

Transforms ClosureOptRef<C2, In, Out> into the more general ClosureRefOneOf2<C1, C2, In, Out> for any C1.

Example
use orx_closure::*;

type Toy = String;
struct Cat {
    name: String,
    favorite_toys: Vec<Toy>,
}
struct Dog {
    name: String,
    nickname: String,
    favorite_toys: Vec<Toy>,
}

struct PresentIdeas<'a> {
    // for cats or dogs
    for_pet: ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &'a str, [Toy]>,
}

let dogs = vec![Dog {
    name: "luke".to_string(),
    nickname: "dogzilla".to_string(),
    favorite_toys: vec!["toy turtle".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(dogs)
        .fun_option_ref(|dogs, name| {
            dogs.iter()
                .find(|dog| dog.name == name || dog.nickname == name)
                .map(|dog| dog.favorite_toys.as_slice())
        })
        // transforms        : ClosureOptRef<Vec<Dog>, &str, [Toy]>
        // into more general : ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &str, [Toy]>
        .into_oneof2_var2(),
};
assert_eq!(
    Some(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("luke")
);
assert_eq!(
    Some(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("dogzilla")
);
assert!(present_ideas.for_pet.call("tux").is_none());
source§

impl<Capture, In, Out: ?Sized> ClosureOptRef<Capture, In, Out>

source

pub fn into_oneof3_var1<Var2, Var3>( self ) -> ClosureOptRefOneOf3<Capture, Var2, Var3, In, Out>

Transforms ClosureOptRef<C1, In, Out> into the more general ClosureRefOneOf3<C1, C2, C3, In, Out> for any C2 and C3.

Example

The example below illustrates the usage of the closure over two possible types of captures; however, ClosureOptRefOneOf3 is only a generalization of the below for three different capture types.

use orx_closure::*;

type Toy = String;
struct Cat {
    name: String,
    favorite_toys: Vec<Toy>,
}
struct Dog {
    name: String,
    nickname: String,
    favorite_toys: Vec<Toy>,
}

struct PresentIdeas<'a> {
    // for cats or dogs
    for_pet: ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &'a str, [Toy]>,
}

// cats
let cats = vec![Cat {
    name: "bella".to_string(),
    favorite_toys: vec!["ball".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(cats)
        .fun_option_ref(|cats, name| {
            cats.iter()
                .find(|cat| cat.name == name)
                .map(|cat| cat.favorite_toys.as_slice())
        })
        // transforms        : ClosureOptRef<Vec<Cat>, &str, [Toy]>
        // into more general : ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &str, [Toy]>
        .into_oneof2_var1(),
};

assert_eq!(
    Some(vec!["ball".to_string()].as_slice()),
    present_ideas.for_pet.call("bella")
);
assert!(present_ideas.for_pet.call("luna").is_none());
source

pub fn into_oneof3_var2<Var1, Var3>( self ) -> ClosureOptRefOneOf3<Var1, Capture, Var3, In, Out>

Transforms ClosureOptRef<C2, In, Out> into the more general ClosureRefOneOf3<C1, C2, C3, In, Out> for any C1 and C3.

Example

The example below illustrates the usage of the closure over two possible types of captures; however, ClosureOptRefOneOf3 is only a generalization of the below for three different capture types.

use orx_closure::*;

type Toy = String;
struct Cat {
    name: String,
    favorite_toys: Vec<Toy>,
}
struct Dog {
    name: String,
    nickname: String,
    favorite_toys: Vec<Toy>,
}

struct PresentIdeas<'a> {
    // for cats or dogs
    for_pet: ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &'a str, [Toy]>,
}

let dogs = vec![Dog {
    name: "luke".to_string(),
    nickname: "dogzilla".to_string(),
    favorite_toys: vec!["toy turtle".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(dogs)
        .fun_option_ref(|dogs, name| {
            dogs.iter()
                .find(|dog| dog.name == name || dog.nickname == name)
                .map(|dog| dog.favorite_toys.as_slice())
        })
        // transforms        : ClosureOptRef<Vec<Dog>, &str, [Toy]>
        // into more general : ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &str, [Toy]>
        .into_oneof2_var2(),
};
assert_eq!(
    Some(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("luke")
);
assert_eq!(
    Some(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("dogzilla")
);
assert!(present_ideas.for_pet.call("tux").is_none());
source

pub fn into_oneof3_var3<Var1, Var2>( self ) -> ClosureOptRefOneOf3<Var1, Var2, Capture, In, Out>

Transforms ClosureOptRef<C3, In, Out> into the more general ClosureRefOneOf3<C1, C2, C3, In, Out> for any C2 and C3.

Example

The example below illustrates the usage of the closure over two possible types of captures; however, ClosureOptRefOneOf3 is only a generalization of the below for three different capture types.

use orx_closure::*;

type Toy = String;
struct Cat {
    name: String,
    favorite_toys: Vec<Toy>,
}
struct Dog {
    name: String,
    nickname: String,
    favorite_toys: Vec<Toy>,
}

struct PresentIdeas<'a> {
    // for cats or dogs
    for_pet: ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &'a str, [Toy]>,
}

let dogs = vec![Dog {
    name: "luke".to_string(),
    nickname: "dogzilla".to_string(),
    favorite_toys: vec!["toy turtle".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(dogs)
        .fun_option_ref(|dogs, name| {
            dogs.iter()
                .find(|dog| dog.name == name || dog.nickname == name)
                .map(|dog| dog.favorite_toys.as_slice())
        })
        // transforms        : ClosureOptRef<Vec<Dog>, &str, [Toy]>
        // into more general : ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &str, [Toy]>
        .into_oneof2_var2(),
};
assert_eq!(
    Some(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("luke")
);
assert_eq!(
    Some(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("dogzilla")
);
assert!(present_ideas.for_pet.call("tux").is_none());
source§

impl<Capture, In, Out: ?Sized> ClosureOptRef<Capture, In, Out>

source

pub fn into_oneof4_var1<Var2, Var3, Var4>( self ) -> ClosureOptRefOneOf4<Capture, Var2, Var3, Var4, In, Out>

Transforms ClosureOptRef<C1, In, Out> into the more general ClosureRefOneOf4<C1, C2, C3, C4, In, Out> for any C2, C3 and C4.

Example

The example below illustrates the usage of the closure over two possible types of captures; however, ClosureOptRefOneOf4 is only a generalization of the below for three different capture types.

use orx_closure::*;

type Toy = String;
struct Cat {
    name: String,
    favorite_toys: Vec<Toy>,
}
struct Dog {
    name: String,
    nickname: String,
    favorite_toys: Vec<Toy>,
}

struct PresentIdeas<'a> {
    // for cats or dogs
    for_pet: ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &'a str, [Toy]>,
}

// cats
let cats = vec![Cat {
    name: "bella".to_string(),
    favorite_toys: vec!["ball".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(cats)
        .fun_option_ref(|cats, name| {
            cats.iter()
                .find(|cat| cat.name == name)
                .map(|cat| cat.favorite_toys.as_slice())
        })
        // transforms        : ClosureOptRef<Vec<Cat>, &str, [Toy]>
        // into more general : ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &str, [Toy]>
        .into_oneof2_var1(),
};

assert_eq!(
    Some(vec!["ball".to_string()].as_slice()),
    present_ideas.for_pet.call("bella")
);
assert!(present_ideas.for_pet.call("luna").is_none());
source

pub fn into_oneof4_var2<Var1, Var3, Var4>( self ) -> ClosureOptRefOneOf4<Var1, Capture, Var3, Var4, In, Out>

Transforms ClosureOptRef<C2, In, Out> into the more general ClosureRefOneOf4<C1, C2, C3, C4, In, Out> for any C1, C3 and C4.

Example

The example below illustrates the usage of the closure over two possible types of captures; however, ClosureOptRefOneOf3 is only a generalization of the below for three different capture types.

use orx_closure::*;

type Toy = String;
struct Cat {
    name: String,
    favorite_toys: Vec<Toy>,
}
struct Dog {
    name: String,
    nickname: String,
    favorite_toys: Vec<Toy>,
}

struct PresentIdeas<'a> {
    // for cats or dogs
    for_pet: ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &'a str, [Toy]>,
}

let dogs = vec![Dog {
    name: "luke".to_string(),
    nickname: "dogzilla".to_string(),
    favorite_toys: vec!["toy turtle".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(dogs)
        .fun_option_ref(|dogs, name| {
            dogs.iter()
                .find(|dog| dog.name == name || dog.nickname == name)
                .map(|dog| dog.favorite_toys.as_slice())
        })
        // transforms        : ClosureOptRef<Vec<Dog>, &str, [Toy]>
        // into more general : ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &str, [Toy]>
        .into_oneof2_var2(),
};
assert_eq!(
    Some(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("luke")
);
assert_eq!(
    Some(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("dogzilla")
);
assert!(present_ideas.for_pet.call("tux").is_none());
source

pub fn into_oneof4_var3<Var1, Var2, Var4>( self ) -> ClosureOptRefOneOf4<Var1, Var2, Capture, Var4, In, Out>

Transforms ClosureOptRef<C3, In, Out> into the more general ClosureRefOneOf4<C1, C2, C3, C4, In, Out> for any C1, C2 and C4.

Example

The example below illustrates the usage of the closure over two possible types of captures; however, ClosureOptRefOneOf3 is only a generalization of the below for three different capture types.

use orx_closure::*;

type Toy = String;
struct Cat {
    name: String,
    favorite_toys: Vec<Toy>,
}
struct Dog {
    name: String,
    nickname: String,
    favorite_toys: Vec<Toy>,
}

struct PresentIdeas<'a> {
    // for cats or dogs
    for_pet: ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &'a str, [Toy]>,
}

let dogs = vec![Dog {
    name: "luke".to_string(),
    nickname: "dogzilla".to_string(),
    favorite_toys: vec!["toy turtle".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(dogs)
        .fun_option_ref(|dogs, name| {
            dogs.iter()
                .find(|dog| dog.name == name || dog.nickname == name)
                .map(|dog| dog.favorite_toys.as_slice())
        })
        // transforms        : ClosureOptRef<Vec<Dog>, &str, [Toy]>
        // into more general : ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &str, [Toy]>
        .into_oneof2_var2(),
};
assert_eq!(
    Some(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("luke")
);
assert_eq!(
    Some(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("dogzilla")
);
assert!(present_ideas.for_pet.call("tux").is_none());
source

pub fn into_oneof4_var4<Var1, Var2, Var3>( self ) -> ClosureOptRefOneOf4<Var1, Var2, Var3, Capture, In, Out>

Transforms ClosureOptRef<C4, In, Out> into the more general ClosureRefOneOf4<C1, C2, C3, C4, In, Out> for any C1, C2 and C3.

Example

The example below illustrates the usage of the closure over two possible types of captures; however, ClosureOptRefOneOf3 is only a generalization of the below for three different capture types.

use orx_closure::*;

type Toy = String;
struct Cat {
    name: String,
    favorite_toys: Vec<Toy>,
}
struct Dog {
    name: String,
    nickname: String,
    favorite_toys: Vec<Toy>,
}

struct PresentIdeas<'a> {
    // for cats or dogs
    for_pet: ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &'a str, [Toy]>,
}

let dogs = vec![Dog {
    name: "luke".to_string(),
    nickname: "dogzilla".to_string(),
    favorite_toys: vec!["toy turtle".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(dogs)
        .fun_option_ref(|dogs, name| {
            dogs.iter()
                .find(|dog| dog.name == name || dog.nickname == name)
                .map(|dog| dog.favorite_toys.as_slice())
        })
        // transforms        : ClosureOptRef<Vec<Dog>, &str, [Toy]>
        // into more general : ClosureOptRefOneOf2<Vec<Cat>, Vec<Dog>, &str, [Toy]>
        .into_oneof2_var2(),
};
assert_eq!(
    Some(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("luke")
);
assert_eq!(
    Some(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("dogzilla")
);
assert!(present_ideas.for_pet.call("tux").is_none());

Trait Implementations§

source§

impl<Capture: Clone, In: Clone, Out: Clone + ?Sized> Clone for ClosureOptRef<Capture, In, Out>

source§

fn clone(&self) -> ClosureOptRef<Capture, In, Out>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<Capture: Debug, In, Out: ?Sized> Debug for ClosureOptRef<Capture, In, Out>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<Capture, In, Out: ?Sized> FunOptRef<In, Out> for ClosureOptRef<Capture, In, Out>

source§

fn call(&self, input: In) -> Option<&Out>

Calls the function with the given input and returns the produced output.

Auto Trait Implementations§

§

impl<Capture, In, Out: ?Sized> RefUnwindSafe for ClosureOptRef<Capture, In, Out>where Capture: RefUnwindSafe,

§

impl<Capture, In, Out: ?Sized> Send for ClosureOptRef<Capture, In, Out>where Capture: Send,

§

impl<Capture, In, Out: ?Sized> Sync for ClosureOptRef<Capture, In, Out>where Capture: Sync,

§

impl<Capture, In, Out: ?Sized> Unpin for ClosureOptRef<Capture, In, Out>where Capture: Unpin,

§

impl<Capture, In, Out: ?Sized> UnwindSafe for ClosureOptRef<Capture, In, Out>where Capture: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.