-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: simplify
demux_enum()
, somewhat improves error messages #…
- Loading branch information
1 parent
041bcf9
commit 826dbd9
Showing
18 changed files
with
289 additions
and
181 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,22 @@ | ||
//! Traits for the `demux_enum` derive and operator. | ||
//! Trait for the `demux_enum` derive and operator. | ||
|
||
pub use hydroflow_macro::DemuxEnum; | ||
use pusherator::demux::PusheratorList; | ||
use pusherator::Pusherator; | ||
use variadics::Variadic; | ||
|
||
/// Trait for use with the `demux_enum` operator. | ||
/// | ||
/// This trait is meant to be derived: `#[derive(DemuEnum)]`. | ||
pub trait DemuxEnum<Nexts>: DemuxEnumItems | ||
where | ||
Nexts: PusheratorListForItems<Self::Items>, | ||
{ | ||
/// Pushes self into the corresponding output pusherator. | ||
fn demux_enum(self, outputs: &mut Nexts); | ||
} | ||
|
||
/// Fixed output item list for [`DemuxEnum`]. | ||
/// This trait is meant to be derived: `#[derive(DemuxEnum)]`. | ||
/// | ||
/// This trait is meant to be derived: `#[derive(DemuEnum)]`. | ||
pub trait DemuxEnumItems { | ||
/// A `var_type!(...)` list of items corresponding to each variant's output type. | ||
type Items: Variadic; | ||
/// The derive will implement this such that `Outputs` can be any tuple where each item is a | ||
/// `Pusherator` that corresponds to each of the variants of the tuple, in alphabetic order. | ||
#[diagnostic::on_unimplemented( | ||
note = "Ensure there is exactly one output for each enum variant.", | ||
note = "Ensure that the type for each output is a tuple of the field for the variant: `()`, `(a,)`, or `(a, b, ...)`." | ||
)] | ||
pub trait DemuxEnum<Outputs>: DemuxEnumBase { | ||
/// Pushes self into the corresponding output pusherator in `outputs`. | ||
fn demux_enum(self, outputs: &mut Outputs); | ||
} | ||
|
||
/// Helper trait to bound a [`PusheratorList`] variadic to some coresponding item list variadic. | ||
/// | ||
/// A pusherator list `var_type!(PushA, PushB, PushC)` implements `PusheratorListForItems<var_type!(ItemA, ItemB, ItemC)>`, | ||
/// where `PushA: Pusherator<Item = ItemA>`, etc. | ||
pub trait PusheratorListForItems<Items>: PusheratorList | ||
where | ||
Items: Variadic, | ||
{ | ||
} | ||
impl<HeadPush, RestPush, Head, Rest> PusheratorListForItems<(Head, Rest)> for (HeadPush, RestPush) | ||
where | ||
HeadPush: Pusherator<Item = Head>, | ||
RestPush: PusheratorListForItems<Rest>, | ||
Rest: Variadic, | ||
{ | ||
} | ||
impl PusheratorListForItems<()> for () {} | ||
/// Base implementation to constrain that `DemuxEnum<SOMETHING>` is implemented. | ||
#[diagnostic::on_unimplemented(note = "Use `#[derive(hydroflow::DemuxEnum)]`")] | ||
pub trait DemuxEnumBase {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 16 additions & 7 deletions
23
hydroflow/tests/compile-fail/surface_demuxenum_port_missing.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,25 @@ | ||
error[E0308]: mismatched types | ||
--> tests/compile-fail/surface_demuxenum_port_missing.rs:12:18 | ||
--> tests/compile-fail/surface_demuxenum_port_missing.rs:17:15 | ||
| | ||
12 | let mut df = hydroflow_syntax! { | ||
| __________________^ | ||
| __________________- | ||
13 | | my_demux = source_iter([ | ||
14 | | Shape::Rectangle { w: 10.0, h: 8.0 }, | ||
15 | | Shape::Square(9.0), | ||
... | | ||
16 | | Shape::Circle { r: 5.0 }, | ||
17 | | ]) -> demux_enum::<Shape>(); | ||
| | ^^^^^^^^^^^^^^^^^^^^^ expected a tuple with 3 elements, found one with 2 elements | ||
18 | | my_demux[Rectangle] -> for_each(std::mem::drop); | ||
| | ------------------------ one of the found opaque types | ||
19 | | my_demux[Circle] -> for_each(std::mem::drop); | ||
| | ------------------------ one of the found opaque types | ||
20 | | }; | ||
| |_____^ expected `(_, ())`, found `()` | ||
| |_____- arguments to this function are incorrect | ||
| | ||
= note: expected tuple `(_, ())` | ||
found unit type `()` | ||
= note: this error originates in the macro `$crate::var_expr` which comes from the expansion of the macro `hydroflow_syntax` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
= note: expected mutable reference `&mut (_, _, _)` | ||
found mutable reference `&mut (impl Pusherator<Item = _>, impl Pusherator<Item = _>)` | ||
note: method defined here | ||
--> src/util/demux_enum.rs | ||
| | ||
| fn demux_enum(self, outputs: &mut Outputs); | ||
| ^^^^^^^^^^ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 81 additions & 6 deletions
87
hydroflow/tests/compile-fail/surface_demuxenum_wrongenum.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,86 @@ | ||
error: Output connection conflicts with below ($DIR/tests/compile-fail/surface_demuxenum_wrongenum.rs:21:18) (1/2) | ||
error[E0277]: the trait bound `std::option::Option<()>: DemuxEnumBase` is not satisfied | ||
--> tests/compile-fail/surface_demuxenum_wrongenum.rs:17:28 | ||
| | ||
17 | ]) -> demux_enum::<Option<()>>(); | ||
| ^^^^^^^^^^ the trait `DemuxEnumBase` is not implemented for `std::option::Option<()>` | ||
| | ||
= note: Use `#[derive(hydroflow::DemuxEnum)]` | ||
= help: the trait `DemuxEnumBase` is implemented for `Shape` | ||
note: required by a bound in `check_impl_demux_enum` | ||
--> tests/compile-fail/surface_demuxenum_wrongenum.rs:12:18 | ||
| | ||
12 | let mut df = hydroflow_syntax! { | ||
| __________________^ | ||
13 | | my_demux = source_iter([ | ||
14 | | Shape::Rectangle { w: 10.0, h: 8.0 }, | ||
15 | | Shape::Square(9.0), | ||
... | | ||
20 | | my_demux[Square] -> for_each(std::mem::drop); | ||
21 | | }; | ||
| |_____^ required by this bound in `check_impl_demux_enum` | ||
= note: this error originates in the macro `hydroflow_syntax` (in Nightly builds, run with -Z macro-backtrace for more info) | ||
|
||
error[E0599]: no variant named `Circle` found for enum `std::option::Option<()>` | ||
--> tests/compile-fail/surface_demuxenum_wrongenum.rs:19:18 | ||
| | ||
19 | my_demux[Circle] -> for_each(std::mem::drop); | ||
| ^^^^^^ variant not found in `std::option::Option<()>` | ||
|
||
error[E0599]: no variant named `Rectangle` found for enum `std::option::Option<()>` | ||
--> tests/compile-fail/surface_demuxenum_wrongenum.rs:18:18 | ||
| | ||
18 | my_demux[Rectangle] -> for_each(std::mem::drop); | ||
| ^^^^^^^^^ variant not found in `std::option::Option<()>` | ||
|
||
error[E0599]: no variant named `Square` found for enum `std::option::Option<()>` | ||
--> tests/compile-fail/surface_demuxenum_wrongenum.rs:20:18 | ||
| | ||
20 | my_demux[Square] -> for_each(std::mem::drop); | ||
| ^^^^^^ | ||
| ^^^^^^ variant not found in `std::option::Option<()>` | ||
|
||
error[E0277]: the trait bound `std::option::Option<()>: DemuxEnum<_>` is not satisfied | ||
--> tests/compile-fail/surface_demuxenum_wrongenum.rs:17:15 | ||
| | ||
12 | let mut df = hydroflow_syntax! { | ||
| __________________- | ||
13 | | my_demux = source_iter([ | ||
14 | | Shape::Rectangle { w: 10.0, h: 8.0 }, | ||
15 | | Shape::Square(9.0), | ||
16 | | Shape::Circle { r: 5.0 }, | ||
17 | | ]) -> demux_enum::<Option<()>>(); | ||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `DemuxEnum<_>` is not implemented for `std::option::Option<()>` | ||
... | | ||
20 | | my_demux[Square] -> for_each(std::mem::drop); | ||
21 | | }; | ||
| |_____- required by a bound introduced by this call | ||
| | ||
= note: Ensure there is exactly one output for each enum variant. | ||
= note: Ensure that the type for each output is a tuple of the field for the variant: `()`, `(a,)`, or `(a, b, ...)`. | ||
= help: the trait `DemuxEnum<(__PusheratorCircle, __PusheratorRectangle, __PusheratorSquare)>` is implemented for `Shape` | ||
|
||
error: Output connection conflicts with above ($DIR/tests/compile-fail/surface_demuxenum_wrongenum.rs:20:18) (2/2) | ||
--> tests/compile-fail/surface_demuxenum_wrongenum.rs:21:18 | ||
error[E0271]: type mismatch resolving `<impl Pusherator<Item = Option<()>> as Pusherator>::Item == Shape` | ||
--> tests/compile-fail/surface_demuxenum_wrongenum.rs:17:15 | ||
| | ||
13 | my_demux = source_iter([ | ||
| ____________________- | ||
14 | | Shape::Rectangle { w: 10.0, h: 8.0 }, | ||
15 | | Shape::Square(9.0), | ||
16 | | Shape::Circle { r: 5.0 }, | ||
17 | | ]) -> demux_enum::<Option<()>>(); | ||
| | ^^^^^^^^^^^^^^^^^^^^^^^^^- | ||
| |_______________|________________________| | ||
| | required by a bound introduced by this call | ||
| expected `Shape`, found `Option<()>` | ||
| | ||
= note: expected enum `Shape` | ||
found enum `std::option::Option<()>` | ||
note: required by a bound in `pivot_run_sg_1v1` | ||
--> tests/compile-fail/surface_demuxenum_wrongenum.rs:13:20 | ||
| | ||
21 | my_demux[Square] -> for_each(std::mem::drop); | ||
| ^^^^^^ | ||
13 | my_demux = source_iter([ | ||
| ____________________^ | ||
14 | | Shape::Rectangle { w: 10.0, h: 8.0 }, | ||
15 | | Shape::Square(9.0), | ||
16 | | Shape::Circle { r: 5.0 }, | ||
17 | | ]) -> demux_enum::<Option<()>>(); | ||
| |________________________________________^ required by this bound in `pivot_run_sg_1v1` |
23 changes: 23 additions & 0 deletions
23
hydroflow/tests/compile-fail/surface_demuxenum_wrongfields_1.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
use hydroflow::util::demux_enum::DemuxEnum; | ||
use hydroflow::hydroflow_syntax; | ||
|
||
fn main() { | ||
#[derive(DemuxEnum)] | ||
enum Shape { | ||
Square(f64), | ||
Rectangle { w: f64, h: f64 }, | ||
Circle { r: f64 }, | ||
} | ||
|
||
let mut df = hydroflow_syntax! { | ||
my_demux = source_iter([ | ||
Shape::Rectangle { w: 10.0, h: 8.0 }, | ||
Shape::Square(9.0), | ||
Shape::Circle { r: 5.0 }, | ||
]) -> demux_enum::<Shape>(); | ||
my_demux[Rectangle] -> for_each(std::mem::drop); | ||
my_demux[Circle] -> for_each(std::mem::drop); | ||
my_demux[Square] -> for_each(|side: u32| ()); | ||
}; | ||
df.run_available(); | ||
} |
29 changes: 29 additions & 0 deletions
29
hydroflow/tests/compile-fail/surface_demuxenum_wrongfields_1.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
error[E0271]: type mismatch resolving `<impl Pusherator<Item = u32> as Pusherator>::Item == (f64,)` | ||
--> tests/compile-fail/surface_demuxenum_wrongfields_1.rs:17:15 | ||
| | ||
12 | let mut df = hydroflow_syntax! { | ||
| __________________- | ||
13 | | my_demux = source_iter([ | ||
14 | | Shape::Rectangle { w: 10.0, h: 8.0 }, | ||
15 | | Shape::Square(9.0), | ||
16 | | Shape::Circle { r: 5.0 }, | ||
17 | | ]) -> demux_enum::<Shape>(); | ||
| | ^^^^^^^^^^^^^^^^^^^^^ expected `(f64,)`, found `u32` | ||
... | | ||
20 | | my_demux[Square] -> for_each(|side: u32| ()); | ||
21 | | }; | ||
| |_____- required by a bound introduced by this call | ||
| | ||
= note: expected tuple `(f64,)` | ||
found type `u32` | ||
note: required for `Shape` to implement `DemuxEnum<(impl Pusherator<Item = (f64,)>, impl Pusherator<Item = (f64, f64)>, impl Pusherator<Item = u32>)>` | ||
--> tests/compile-fail/surface_demuxenum_wrongfields_1.rs:5:14 | ||
| | ||
5 | #[derive(DemuxEnum)] | ||
| ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro | ||
6 | enum Shape { | ||
| ^^^^^ | ||
= note: associated types for the current `impl` cannot be restricted in `where` clauses | ||
= note: associated types for the current `impl` cannot be restricted in `where` clauses | ||
= note: associated types for the current `impl` cannot be restricted in `where` clauses | ||
= note: this error originates in the derive macro `DemuxEnum` (in Nightly builds, run with -Z macro-backtrace for more info) |
Oops, something went wrong.