pub struct ClosureResRefOneOf2<C1, C2, In, Out: ?Sized, Error> { /* private fields */ }
Expand description

ClosureResRefOneOf2<C1, C2, In, Out, Error> is a union of two closures:

  • ClosureResRef<C1, In, Out, Error>
  • ClosureResRef<C2, In, Out, Error>

This is useful when it is possible that the closure might capture and work with either of the two types of data C1 and C2.

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

Note that, unlike trait objects of fn-traits, ClosureResRefOneOf2 auto-implements Clone given that captured data variants are cloneable.

Instead of ClosureOneOf2; this closure variant is particularly useful when we capture the data by value and return a result of a reference.

Example

use orx_closure::*;

type Toy = String;
type MyErr = &'static str;
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: ClosureResRefOneOf2<Vec<Cat>, Vec<Dog>, &'a str, [Toy], MyErr>,
}

// cats
let cats = vec![Cat {
    name: "bella".to_string(),
    favorite_toys: vec!["ball".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(cats)
        .fun_result_ref(|cats, name| {
            cats.iter()
                .find(|cat| cat.name == name)
                .map(|cat| cat.favorite_toys.as_slice())
                .ok_or("pet name is absent")
        })
        .into_oneof2_var1(),
};

assert_eq!(
    Ok(vec!["ball".to_string()].as_slice()),
    present_ideas.for_pet.call("bella")
);
assert_eq!(
    Err("pet name is absent"),
    present_ideas.for_pet.call("luna")
);

// dogs
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_result_ref(|dogs, name| {
            dogs.iter()
                .find(|dog| dog.name == name || dog.nickname == name)
                .map(|dog| dog.favorite_toys.as_slice())
                .ok_or("pet name is absent")
        })
        .into_oneof2_var2(),
};
assert_eq!(
    Ok(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("luke")
);
assert_eq!(
    Ok(vec!["toy turtle".to_string()].as_slice()),
    present_ideas.for_pet.call("dogzilla")
);
assert_eq!(Err("pet name is absent"), present_ideas.for_pet.call("tux"));

Implementations§

source§

impl<C1, C2, In, Out: ?Sized, Error> ClosureResRefOneOf2<C1, C2, In, Out, Error>

source

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

Calls the closure with the given input.

Example
use orx_closure::*;

type Toy = String;
type MyErr = &'static str;
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: ClosureResRefOneOf2<Vec<Cat>, Vec<Dog>, &'a str, [Toy], MyErr>,
}

// cats
let cats = vec![Cat {
    name: "bella".to_string(),
    favorite_toys: vec!["ball".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(cats)
        .fun_result_ref(|cats, name| {
            cats.iter()
                .find(|cat| cat.name == name)
                .map(|cat| cat.favorite_toys.as_slice())
                .ok_or("pet name is absent")
        })
        .into_oneof2_var1(),
};

// calling the closure with different pat names
assert_eq!(
    Ok(vec!["ball".to_string()].as_slice()),
    present_ideas.for_pet.call("bella")
);
assert_eq!(
    Err("pet name is absent"),
    present_ideas.for_pet.call("luna")
);
source

pub fn into_captured_data(self) -> OneOf2<C1, C2>

Consumes the closure and returns back the captured data.

Examples
use orx_closure::*;

type Toy = String;
type MyErr = &'static str;

#[derive(Debug, Clone, PartialEq, Eq)]
struct Cat {
    name: String,
    favorite_toys: Vec<Toy>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
struct Dog {
    name: String,
    nickname: String,
    favorite_toys: Vec<Toy>,
}

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

// cats
let cats = vec![Cat {
    name: "bella".to_string(),
    favorite_toys: vec!["ball".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(cats.clone())
        .fun_result_ref(|cats, name| {
            cats.iter()
                .find(|cat| cat.name == name)
                .map(|cat| cat.favorite_toys.as_slice())
                .ok_or("pet name is absent")
        })
        .into_oneof2_var1(),
};

// calling the closure with different pat names
assert_eq!(
    Ok(vec!["ball".to_string()].as_slice()),
    present_ideas.for_pet.call("bella")
);
assert_eq!(
    Err("pet name is absent"),
    present_ideas.for_pet.call("luna")
);

// get back the captured data which can be one of the two options: cats or dogs:

let data = present_ideas.for_pet.into_captured_data();

assert_eq!(data, OneOf2::Variant1(cats));
source

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

Returns the closure as an impl Fn(In) -> Result<&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::*;

type Toy = String;
type MyErr = &'static str;
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: ClosureResRefOneOf2<Vec<Cat>, Vec<Dog>, &'a str, [Toy], MyErr>,
}

// cats
let cats = vec![Cat {
    name: "bella".to_string(),
    favorite_toys: vec!["ball".to_string()],
}];
let present_ideas = PresentIdeas {
    for_pet: Capture(cats)
        .fun_result_ref(|cats, name| {
            cats.iter()
                .find(|cat| cat.name == name)
                .map(|cat| cat.favorite_toys.as_slice())
                .ok_or("pet name is absent")
        })
        .into_oneof2_var1(),
};

// function accepting an instance of the `Fn(&str) -> &[Toy]` trait
fn create_presents<'a, F: Fn(&'a str) -> Result<&'a [Toy], MyErr>>(present_ideas_for: F) -> Vec<Toy> {
    ["bella", "luna"]
        .iter()
        .flat_map(|name| present_ideas_for(name).unwrap_or(&[]).iter().cloned())
        .collect()
}

// we can conveniently create the `Fn` with `as_fn`
let presents = create_presents(present_ideas.for_pet.as_fn());
assert_eq!(&["ball".to_string()], presents.as_slice());

Trait Implementations§

source§

impl<C1: Clone, C2: Clone, In: Clone, Out: Clone + ?Sized, Error: Clone> Clone for ClosureResRefOneOf2<C1, C2, In, Out, Error>

source§

fn clone(&self) -> ClosureResRefOneOf2<C1, C2, In, Out, Error>

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<C1: Debug, C2: Debug, In: Debug, Out: Debug + ?Sized, Error: Debug> Debug for ClosureResRefOneOf2<C1, C2, In, Out, Error>

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<C1, C2, In, Out: ?Sized, Error> RefUnwindSafe for ClosureResRefOneOf2<C1, C2, In, Out, Error>where C1: RefUnwindSafe, C2: RefUnwindSafe,

§

impl<C1, C2, In, Out: ?Sized, Error> Send for ClosureResRefOneOf2<C1, C2, In, Out, Error>where C1: Send, C2: Send,

§

impl<C1, C2, In, Out: ?Sized, Error> Sync for ClosureResRefOneOf2<C1, C2, In, Out, Error>where C1: Sync, C2: Sync,

§

impl<C1, C2, In, Out: ?Sized, Error> Unpin for ClosureResRefOneOf2<C1, C2, In, Out, Error>where C1: Unpin, C2: Unpin,

§

impl<C1, C2, In, Out: ?Sized, Error> UnwindSafe for ClosureResRefOneOf2<C1, C2, In, Out, Error>where C1: UnwindSafe, C2: 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.