Struct orx_closure::ClosureOneOf3
source · 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
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, 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