types: enum: buff up tests
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
use crate::compound::peano::{P0, Peano, PNext};
|
use crate::compound::peano::{P0, Peano, PNext};
|
||||||
use crate::compound::list::{self, Indexable, IntoList};
|
use crate::compound::list::{self, Indexable, IntoList, List};
|
||||||
|
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
@@ -19,6 +19,8 @@ pub trait DiscriminantCodable<P: Peano>: Sized {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// discriminant which encodes up to *but not including* P.
|
/// discriminant which encodes up to *but not including* P.
|
||||||
|
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||||
|
#[cfg_attr(feature = "fmt", derive(Debug))]
|
||||||
#[derive(Copy, Clone, Default, PartialEq)]
|
#[derive(Copy, Clone, Default, PartialEq)]
|
||||||
pub struct Discr<P: Peano>(u32, P::Unit);
|
pub struct Discr<P: Peano>(u32, P::Unit);
|
||||||
|
|
||||||
@@ -68,7 +70,7 @@ pub trait DiscrHandler<N: Peano, R> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// helper used to call F with some (yet-to-be-determined) index of I
|
/// helper used to call F with some (yet-to-be-determined) index of I
|
||||||
struct DispatchIndexable<I, F> {
|
pub struct DispatchIndexable<I, F> {
|
||||||
indexable: I,
|
indexable: I,
|
||||||
f: F,
|
f: F,
|
||||||
}
|
}
|
||||||
@@ -131,7 +133,9 @@ where
|
|||||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
||||||
#[cfg_attr(feature = "fmt", derive(Debug))]
|
#[cfg_attr(feature = "fmt", derive(Debug))]
|
||||||
#[derive(Copy, Clone, Default, PartialEq)]
|
#[derive(Copy, Clone, Default, PartialEq)]
|
||||||
struct Enum<D, L>(D, L);
|
pub struct Enum<D, L>(D, L);
|
||||||
|
|
||||||
|
pub type InternallyDiscriminated<Args> = Enum<(), List<Args>>;
|
||||||
|
|
||||||
impl<P: Peano, L> Enum<(Discr<P>,), L> {
|
impl<P: Peano, L> Enum<(Discr<P>,), L> {
|
||||||
pub fn new<Variants>(v: Variants) -> Self
|
pub fn new<Variants>(v: Variants) -> Self
|
||||||
@@ -151,7 +155,7 @@ impl<L> Enum<(), L> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait EnumRequirements {
|
pub trait EnumRequirements {
|
||||||
type NumVariants: Peano;
|
type NumVariants: Peano;
|
||||||
fn decode_discr(&self) -> Discr<Self::NumVariants>;
|
fn decode_discr(&self) -> Discr<Self::NumVariants>;
|
||||||
fn encode_discr(&mut self, d: Discr<Self::NumVariants>);
|
fn encode_discr(&mut self, d: Discr<Self::NumVariants>);
|
||||||
@@ -191,7 +195,7 @@ where
|
|||||||
Self: EnumRequirements
|
Self: EnumRequirements
|
||||||
{
|
{
|
||||||
/// invoke the closure on the active variant, passing the variant by-value
|
/// invoke the closure on the active variant, passing the variant by-value
|
||||||
fn dispatch<'a, F, R>(&'a self, f: F) -> R
|
pub fn dispatch<'a, F, R>(&'a self, f: F) -> R
|
||||||
where
|
where
|
||||||
DispatchIndexable<&'a L, F>: DiscrHandler<<Self as EnumRequirements>::NumVariants, R>
|
DispatchIndexable<&'a L, F>: DiscrHandler<<Self as EnumRequirements>::NumVariants, R>
|
||||||
{
|
{
|
||||||
@@ -199,14 +203,14 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// invoke the closure on the active variant, passing the variant by mutable reference
|
/// invoke the closure on the active variant, passing the variant by mutable reference
|
||||||
fn dispatch_mut<'a, F, R>(&'a mut self, f: F) -> R
|
pub fn dispatch_mut<'a, F, R>(&'a mut self, f: F) -> R
|
||||||
where
|
where
|
||||||
DispatchIndexable<&'a mut L, F>: DiscrHandler<<Self as EnumRequirements>::NumVariants, R>
|
DispatchIndexable<&'a mut L, F>: DiscrHandler<<Self as EnumRequirements>::NumVariants, R>
|
||||||
{
|
{
|
||||||
self.decode_discr().dispatch(DispatchIndexable::new(&mut self.1, f))
|
self.decode_discr().dispatch(DispatchIndexable::new(&mut self.1, f))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set<P>(&mut self, value: L::Element)
|
pub fn set<P>(&mut self, value: L::Element)
|
||||||
where
|
where
|
||||||
P: Peano,
|
P: Peano,
|
||||||
L: Indexable<P>,
|
L: Indexable<P>,
|
||||||
@@ -310,8 +314,10 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn internal_discr() {
|
fn internal_discr() {
|
||||||
let mut e: Enum<(), List<(BoxedF32, i32, u8)>> = Enum::default();
|
type E = Enum<(), List<(BoxedF32, i32, u8)>>;
|
||||||
|
assert_eq!(<E as EnumRequirements>::NumVariants::VALUE, 3);
|
||||||
|
|
||||||
|
let mut e: E = Enum::default();
|
||||||
assert_eq!(e.dispatch(ReadReceiver), 0);
|
assert_eq!(e.dispatch(ReadReceiver), 0);
|
||||||
|
|
||||||
e.set::<P0>(BoxedF32(16f32));
|
e.set::<P0>(BoxedF32(16f32));
|
||||||
@@ -329,7 +335,10 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn new() {
|
fn new() {
|
||||||
let e = Enum::new((5u32, 4i32));
|
type E = Enum<(Discr<P2>,), List<(u32, i32)>>;
|
||||||
|
assert_eq!(<E as EnumRequirements>::NumVariants::VALUE, 2);
|
||||||
|
|
||||||
|
let e: E = Enum::new((5u32, 4i32));
|
||||||
assert_eq!(e.dispatch(ReadReceiver), 5);
|
assert_eq!(e.dispatch(ReadReceiver), 5);
|
||||||
|
|
||||||
let e = Enum::internally_discriminated((BoxedF32(4f32), -1i32));
|
let e = Enum::internally_discriminated((BoxedF32(4f32), -1i32));
|
||||||
|
Reference in New Issue
Block a user