use hydroflow::hydroflow_syntax; use hydroflow::util::demux_enum::{DemuxEnum, DemuxEnumBase}; use multiplatform_test::multiplatform_test; use pusherator::for_each::ForEach; #[multiplatform_test] fn test_manual_impl() { use pusherator::Pusherator; enum Shape { Square(usize), Rectangle { w: usize, h: usize }, Circle { r: usize }, } impl DemuxEnum<(Square, Rectangle, Circle)> for Shape where Square: Pusherator, Rectangle: Pusherator, Circle: Pusherator, { fn demux_enum(self, (sq, re, ci): &mut (Square, Rectangle, Circle)) { match self { Self::Square(s) => sq.give(s), Self::Rectangle { w, h } => re.give((w, h)), Self::Circle { r } => ci.give((r,)), } } } impl DemuxEnumBase for Shape {} let vals = [ Shape::Square(5), Shape::Rectangle { w: 5, h: 6 }, Shape::Circle { r: 6 }, ]; let mut nexts = ( ForEach::new(|x| println!("1 {:?}", x)), ForEach::new(|x| println!("2 {:?}", x)), ForEach::new(|x| println!("3 {:?}", x)), ); for val in vals { val.demux_enum(&mut nexts); } } #[multiplatform_test] fn test_derive() { #[derive(DemuxEnum)] enum Shape { Square(usize), Rectangle { w: usize, h: usize }, Circle { r: usize }, } let vals = [ Shape::Square(5), Shape::Rectangle { w: 5, h: 6 }, Shape::Circle { r: 6 }, ]; let mut nexts = ( ForEach::new(|x| println!("1 {:?}", x)), ForEach::new(|x| println!("2 {:?}", x)), ForEach::new(|x| println!("3 {:?}", x)), ); for val in vals { val.demux_enum(&mut nexts); } } #[multiplatform_test] pub fn test_demux_enum() { #[derive(DemuxEnum)] enum Shape { Square(f64), Rectangle { w: f64, h: f64 }, Circle { r: f64 }, } let mut df = hydroflow_syntax! { my_demux = source_iter([ Shape::Square(9.0), Shape::Rectangle { w: 10.0, h: 8.0 }, Shape::Circle { r: 5.0 }, ]) -> demux_enum::(); my_demux[Square] -> map(|(s,)| s * s) -> out; my_demux[Circle] -> map(|(r,)| std::f64::consts::PI * r * r) -> out; my_demux[Rectangle] -> map(|(w, h)| w * h) -> out; out = union() -> for_each(|area| println!("Area: {}", area)); }; df.run_available(); } #[multiplatform_test] pub fn test_demux_enum_generic() { #[derive(DemuxEnum)] enum Shape { Square(N), Rectangle { w: N, h: N }, Circle { r: N }, } fn test(s: N, w: N, h: N, r: N) where N: 'static + Into, { let mut df = hydroflow_syntax! { my_demux = source_iter([ Shape::Square(s), Shape::Rectangle { w, h }, Shape::Circle { r }, ]) -> demux_enum::>(); my_demux[Square] -> map(|(s,)| s.into()) -> map(|s| s * s) -> out; my_demux[Circle] -> map(|(r,)| r.into()) -> map(|r| std::f64::consts::PI * r * r) -> out; my_demux[Rectangle] -> map(|(w, h)| w.into() * h.into()) -> out; out = union() -> for_each(|area| println!("Area: {}", area)); }; df.run_available(); } test::(9., 10., 8., 5.); test::(9, 10, 8, 5); } #[multiplatform_test] fn test_zero_variants() { #[derive(DemuxEnum)] enum Never {} let (_tx, rx) = hydroflow::util::unbounded_channel::(); let mut df = hydroflow_syntax! { source_stream(rx) -> demux_enum::(); }; df.run_available(); } #[multiplatform_test] fn test_one_variant() { #[derive(DemuxEnum)] enum Request { OnlyMessage(T), } let mut df = hydroflow_syntax! { input = source_iter([Request::OnlyMessage("hi")]) -> demux_enum::>(); input[OnlyMessage] -> assert_eq([("hi",)]); }; df.run_available(); }