Struct ClosureOneOf2

Source
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 captured_data(&self) -> OneOf2<&C1, &C2>

Returns a reference to the captured data.

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 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, 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
Source§

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

§

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

§

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