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>
impl<C1, C2, In, Out> ClosureOneOf2<C1, C2, In, Out>
Sourcepub fn call(&self, input: In) -> Out
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);
Sourcepub fn captured_data(&self) -> OneOf2<&C1, &C2>
pub fn captured_data(&self) -> OneOf2<&C1, &C2>
Returns a reference to the captured data.
Sourcepub fn into_captured_data(self) -> OneOf2<C1, C2>
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)));
Sourcepub fn as_fn(&self) -> impl Fn(In) -> Out + '_
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>
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>
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)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source
. Read moreAuto Trait Implementations§
impl<C1, C2, In, Out> Freeze for ClosureOneOf2<C1, C2, In, Out>
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>
impl<C1, C2, In, Out> Sync for ClosureOneOf2<C1, C2, In, Out>
impl<C1, C2, In, Out> Unpin for ClosureOneOf2<C1, C2, In, Out>
impl<C1, C2, In, Out> UnwindSafe for ClosureOneOf2<C1, C2, In, Out>where
C1: UnwindSafe,
C2: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more