Struct orx_closure::ClosureOneOf4
source · pub struct ClosureOneOf4<C1, C2, C3, C4, In, Out> { /* private fields */ }Expand description
ClosureOneOf4<C1, C2, C3, C4, In, Out> is a union of three closures:
Closure<C1, In, Out>Closure<C2, In, Out>Closure<C3, In, Out>Closure<C4, 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, C3 and C4.
It represents the transformation In -> Out.
Note that, unlike trait objects of fn-traits, ClosureOneOf4 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, ClosureOneOf4 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, C4, In, Out> ClosureOneOf4<C1, C2, C3, C4, In, Out>
impl<C1, C2, C3, C4, In, Out> ClosureOneOf4<C1, C2, C3, C4, 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, ClosureOneOf4 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 captured_data(&self) -> OneOf4<&C1, &C2, &C3, &C4>
pub fn captured_data(&self) -> OneOf4<&C1, &C2, &C3, &C4>
Returns a reference to the captured data.
sourcepub fn into_captured_data(self) -> OneOf4<C1, C2, C3, C4>
pub fn into_captured_data(self) -> OneOf4<C1, C2, C3, C4>
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, ClosureOneOf4 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
callmethod, - 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, ClosureOneOf4 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, C4: Clone, In: Clone, Out: Clone> Clone for ClosureOneOf4<C1, C2, C3, C4, In, Out>
impl<C1: Clone, C2: Clone, C3: Clone, C4: Clone, In: Clone, Out: Clone> Clone for ClosureOneOf4<C1, C2, C3, C4, In, Out>
source§fn clone(&self) -> ClosureOneOf4<C1, C2, C3, C4, In, Out>
fn clone(&self) -> ClosureOneOf4<C1, C2, C3, C4, In, Out>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more