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

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

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

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

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

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

Implementations§

source§

impl<C1, C2, In, Out> ClosureOneOf2<C1, C2, In, Out>

source

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

Calls the closure with the given input.

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 into_captured_data(self) -> OneOf2<C1, C2>

Consumes the closure and returns back the captured data.

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.
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, In: Clone, Out: Clone> Clone for ClosureOneOf2<C1, C2, In, Out>

source§

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

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> RefUnwindSafe for ClosureOneOf2<C1, C2, In, Out>where C1: RefUnwindSafe, C2: RefUnwindSafe,

§

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

§

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

§

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

§

impl<C1, C2, In, Out> UnwindSafe for ClosureOneOf2<C1, C2, In, Out>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.