Struct ClosureResRefOneOf4

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

ClosureResRefOneOf4<C1, C2, C3, C4, In, Out, Error> is a union of two closures:

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

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

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

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

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

§Example

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

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, C3, C4, In, Out: ?Sized, Error> ClosureResRefOneOf4<C1, C2, C3, C4, In, Out, Error>

Source

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

Calls the closure with the given input.

§Example

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

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 captured_data(&self) -> OneOf4<&C1, &C2, &C3, &C4>

Returns a reference to the captured data.

Source

pub fn into_captured_data(self) -> OneOf4<C1, C2, C3, C4>

Consumes the closure and returns back the captured data.

§Example

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

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

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

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, C3: Clone, C4: Clone, In: Clone, Out: Clone + ?Sized, Error: Clone> Clone for ClosureResRefOneOf4<C1, C2, C3, C4, In, Out, Error>

Source§

fn clone(&self) -> ClosureResRefOneOf4<C1, C2, C3, C4, In, Out, Error>

Returns a duplicate 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, C3: Debug, C4: Debug, In: Debug, Out: Debug + ?Sized, Error: Debug> Debug for ClosureResRefOneOf4<C1, C2, C3, C4, In, Out, Error>

Source§

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

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

impl<C1, C2, C3, C4, In, Out: ?Sized, Error> FunResRef<In, Out, Error> for ClosureResRefOneOf4<C1, C2, C3, C4, In, Out, Error>

Source§

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

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

Auto Trait Implementations§

§

impl<C1, C2, C3, C4, In, Out, Error> Freeze for ClosureResRefOneOf4<C1, C2, C3, C4, In, Out, Error>
where C1: Freeze, C2: Freeze, C3: Freeze, C4: Freeze, Out: ?Sized,

§

impl<C1, C2, C3, C4, In, Out, Error> RefUnwindSafe for ClosureResRefOneOf4<C1, C2, C3, C4, In, Out, Error>

§

impl<C1, C2, C3, C4, In, Out, Error> Send for ClosureResRefOneOf4<C1, C2, C3, C4, In, Out, Error>
where C1: Send, C2: Send, C3: Send, C4: Send, Out: ?Sized,

§

impl<C1, C2, C3, C4, In, Out, Error> Sync for ClosureResRefOneOf4<C1, C2, C3, C4, In, Out, Error>
where C1: Sync, C2: Sync, C3: Sync, C4: Sync, Out: ?Sized,

§

impl<C1, C2, C3, C4, In, Out, Error> Unpin for ClosureResRefOneOf4<C1, C2, C3, C4, In, Out, Error>
where C1: Unpin, C2: Unpin, C3: Unpin, C4: Unpin, Out: ?Sized,

§

impl<C1, C2, C3, C4, In, Out, Error> UnwindSafe for ClosureResRefOneOf4<C1, C2, C3, C4, In, Out, Error>
where C1: UnwindSafe, C2: UnwindSafe, C3: UnwindSafe, C4: UnwindSafe, Out: ?Sized,

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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 T
where 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

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 T
where U: TryFrom<T>,

Source§

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.