Struct ClosureOneOf3

Source
pub struct ClosureOneOf3<C1, C2, C3, In, Out> { /* private fields */ }
Expand description

ClosureOneOf3<C1, C2, C3, In, Out> is a union of three closures:

  • Closure<C1, In, Out>
  • Closure<C2, In, Out>
  • Closure<C3, In, Out>

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 -> Out.

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

§Example

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

use orx_closure::*;
use std::collections::HashSet;

type Node = usize; // for brevity
type Edge = (Node, Node); // for brevity

// captures either () or Vec<HashSet<Node>>
type PrecedenceClosure = ClosureOneOf2<(), Vec<HashSet<Node>>, Edge, bool>;

struct Precedence(PrecedenceClosure);

impl Precedence {
    fn new_variant1(closure: Closure<(), Edge, bool>) -> Self {
        Self(closure.into_oneof2_var1())
    }
    fn new_variant2(closure: Closure<Vec<HashSet<Node>>, Edge, bool>) -> Self {
        Self(closure.into_oneof2_var2())
    }

    fn can_precede(&self, edge: Edge) -> bool {
        self.0.call(edge)
    }
}

let allow_all = Precedence::new_variant1(Capture(()).fun(|_, _| true));
assert_eq!(allow_all.can_precede((0, 1)), true);
assert_eq!(allow_all.can_precede((10, 21)), true);

let disallow_all = Precedence::new_variant1(Capture(()).fun(|_, _| false));
assert_eq!(disallow_all.can_precede((0, 1)), false);
assert_eq!(disallow_all.can_precede((10, 21)), false);

let allowed: Vec<HashSet<Node>> = vec![
    HashSet::from_iter([1, 2, 3].into_iter()),
    HashSet::from_iter([2, 3].into_iter()),
    HashSet::from_iter([3].into_iter()),
    HashSet::from_iter([0].into_iter()),
];
let from_allowed = Precedence::new_variant2(
    Capture(allowed).fun(|allowed, edge| allowed[edge.0].contains(&edge.1)),
);
assert_eq!(from_allowed.can_precede((1, 3)), true);
assert_eq!(from_allowed.can_precede((2, 1)), false);

Implementations§

Source§

impl<C1, C2, C3, In, Out> ClosureOneOf3<C1, C2, C3, In, Out>

Source

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

Calls the closure with the given input.

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

§Example
use orx_closure::*;
use std::collections::HashSet;

type Node = usize; // for brevity
type Edge = (Node, Node); // for brevity

// captures either () or Vec<HashSet<Node>>
type PrecedenceClosure = ClosureOneOf2<(), Vec<HashSet<Node>>, Edge, bool>;

struct Precedence(PrecedenceClosure);

impl Precedence {
    fn new_variant1(closure: Closure<(), Edge, bool>) -> Self {
        Self(closure.into_oneof2_var1())
    }
    fn new_variant2(closure: Closure<Vec<HashSet<Node>>, Edge, bool>) -> Self {
        Self(closure.into_oneof2_var2())
    }

    fn can_precede(&self, edge: Edge) -> bool {
        self.0.call(edge)
    }
}

let allow_all = Precedence::new_variant1(Capture(()).fun(|_, _| true));
assert_eq!(allow_all.can_precede((0, 1)), true);
assert_eq!(allow_all.can_precede((10, 21)), true);

let disallow_all = Precedence::new_variant1(Capture(()).fun(|_, _| false));
assert_eq!(disallow_all.can_precede((0, 1)), false);
assert_eq!(disallow_all.can_precede((10, 21)), false);

let allowed: Vec<HashSet<Node>> = vec![
    HashSet::from_iter([1, 2, 3].into_iter()),
    HashSet::from_iter([2, 3].into_iter()),
    HashSet::from_iter([3].into_iter()),
    HashSet::from_iter([0].into_iter()),
];
let from_allowed = Precedence::new_variant2(
    Capture(allowed).fun(|allowed, edge| allowed[edge.0].contains(&edge.1)),
);
assert_eq!(from_allowed.can_precede((1, 3)), true);
assert_eq!(from_allowed.can_precede((2, 1)), false);
Source

pub fn captured_data(&self) -> OneOf3<&C1, &C2, &C3>

Returns a reference to the captured data.

Source

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

Consumes the closure and returns back the captured data.

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

§Example
use orx_closure::*;
use std::collections::HashSet;

type Node = usize; // for brevity
type Edge = (Node, Node); // for brevity

// captures either () or Vec<HashSet<Node>>
type PrecedenceClosure = ClosureOneOf2<(), Vec<HashSet<Node>>, Edge, bool>;

struct Precedence(PrecedenceClosure);

impl Precedence {
    fn new_variant1(closure: Closure<(), Edge, bool>) -> Self {
        Self(closure.into_oneof2_var1())
    }
    fn new_variant2(closure: Closure<Vec<HashSet<Node>>, Edge, bool>) -> Self {
        Self(closure.into_oneof2_var2())
    }

    fn can_precede(&self, edge: Edge) -> bool {
        self.0.call(edge)
    }
}

let allowed: Vec<HashSet<Node>> = vec![
    HashSet::from_iter([1, 2, 3].into_iter()),
    HashSet::from_iter([2, 3].into_iter()),
    HashSet::from_iter([3].into_iter()),
    HashSet::from_iter([0].into_iter()),
];
let from_allowed = Precedence::new_variant2(
    Capture(allowed.clone()).fun(|allowed, edge| allowed[edge.0].contains(&edge.1)),
);
assert_eq!(from_allowed.can_precede((1, 3)), true);
assert_eq!(from_allowed.can_precede((2, 1)), false);

let data = from_allowed.0.into_captured_data();
assert!(matches!(data, OneOf2::Variant2(allowed)));
Source

pub fn as_fn(&self) -> impl Fn(In) -> Out + '_

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

  • to avoid the call method,
  • or pass the closure to functions accepting a function generic over the Fn.

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

§Example
use orx_closure::*;
use std::collections::HashSet;

type Node = usize; // for brevity
type Edge = (Node, Node); // for brevity

// captures either () or Vec<HashSet<Node>>
type PrecedenceClosure = ClosureOneOf2<(), Vec<HashSet<Node>>, Edge, bool>;

struct Precedence(PrecedenceClosure);

impl Precedence {
    fn new_variant1(closure: Closure<(), Edge, bool>) -> Self {
        Self(closure.into_oneof2_var1())
    }
    fn new_variant2(closure: Closure<Vec<HashSet<Node>>, Edge, bool>) -> Self {
        Self(closure.into_oneof2_var2())
    }

    fn get_can_precede(&self) -> impl Fn(Edge) -> bool + '_ {
        self.0.as_fn()
    }
}

let allow_all = Precedence::new_variant1(Capture(()).fun(|_, _| true));
let fun = allow_all.get_can_precede();
assert_eq!(fun((0, 1)), true);
assert_eq!(fun((10, 21)), true);

let disallow_all = Precedence::new_variant1(Capture(()).fun(|_, _| false));
let fun = disallow_all.get_can_precede();
assert_eq!(fun((0, 1)), false);
assert_eq!(fun((10, 21)), false);

let allowed: Vec<HashSet<Node>> = vec![
    HashSet::from_iter([1, 2, 3].into_iter()),
    HashSet::from_iter([2, 3].into_iter()),
    HashSet::from_iter([3].into_iter()),
    HashSet::from_iter([0].into_iter()),
];
let from_allowed = Precedence::new_variant2(
    Capture(allowed).fun(|allowed, edge| allowed[edge.0].contains(&edge.1)),
);
let fun = from_allowed.get_can_precede();
assert_eq!(fun((1, 3)), true);
assert_eq!(fun((2, 1)), false);

Trait Implementations§

Source§

impl<C1: Clone, C2: Clone, C3: Clone, In: Clone, Out: Clone> Clone for ClosureOneOf3<C1, C2, C3, In, Out>

Source§

fn clone(&self) -> ClosureOneOf3<C1, C2, C3, 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<C1: Debug, C2: Debug, C3: Debug, In: Debug, Out: Debug> Debug for ClosureOneOf3<C1, C2, C3, In, Out>

Source§

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

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

impl<C1, C2, C3, In, Out> Fun<In, Out> for ClosureOneOf3<C1, C2, C3, In, Out>

Source§

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

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

Auto Trait Implementations§

§

impl<C1, C2, C3, In, Out> Freeze for ClosureOneOf3<C1, C2, C3, In, Out>
where C1: Freeze, C2: Freeze, C3: Freeze,

§

impl<C1, C2, C3, In, Out> RefUnwindSafe for ClosureOneOf3<C1, C2, C3, In, Out>

§

impl<C1, C2, C3, In, Out> Send for ClosureOneOf3<C1, C2, C3, In, Out>
where C1: Send, C2: Send, C3: Send,

§

impl<C1, C2, C3, In, Out> Sync for ClosureOneOf3<C1, C2, C3, In, Out>
where C1: Sync, C2: Sync, C3: Sync,

§

impl<C1, C2, C3, In, Out> Unpin for ClosureOneOf3<C1, C2, C3, In, Out>
where C1: Unpin, C2: Unpin, C3: Unpin,

§

impl<C1, C2, C3, In, Out> UnwindSafe for ClosureOneOf3<C1, C2, C3, In, Out>
where C1: UnwindSafe, C2: UnwindSafe, C3: UnwindSafe,

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> ToOwned for T
where T: Clone,

Source§

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 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.