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>
impl<C1, C2, C3, In, Out> ClosureOneOf3<C1, C2, C3, In, Out>
Sourcepub fn call(&self, input: In) -> Out
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);
Sourcepub fn into_captured_data(self) -> OneOf3<C1, C2, C3>
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)));
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
.
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>
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>
fn clone(&self) -> ClosureOneOf3<C1, C2, C3, In, Out>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read more