-
Notifications
You must be signed in to change notification settings - Fork 223
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make digital pin traits fallible #97
Conversation
I have two ideas. First, one that I'm pretty sure will work, but might be too heavy-handed. Define the following enum: pub enum ToggleError<OP, SOP> {
OutputPin(OP),
StatefulOutputPin(SOP),
} Use that as the error type for the default implementation, like this: type Error = ToggleError<<P as FallibleOutputPin>::Error, <P as StatefulOutputPin>::Error>; Then update the implementation of fn toggle(&mut self) -> Result<(), Self::Error>{
if self.is_set_low().map_err(|error| ToggleError::StatefulOutputPin(error))? {
self.set_high().map_err(|error| ToggleError::FallibleOutputPin(error))?;
} else {
// ... As I said, pretty sure that will work, but it might be too heavy-handed. My second idea is more elegant, but might not work. Simply make pub trait StatefulOutputPin : FallibleOutputPin {
fn is_set_high(&self) -> Result<bool, Self::Error>;
fn is_set_low(&self) -> Result<bool, Self::Error>;
} Problem solved, because they both have the same error now. The big question is, are there valid use cases where both traits need different errors? Bonus: A third idea that's not implementable right now. Give where <P as FallibleOutputPin>::Error == <P as StatefulOutputPin>::Error This is called an equality constraint, and it's not implemented yet. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me, thank you @eldruin!
There are two reasons I'm not approving this right now:
- The outstanding problem with the
ToggleableOutputPin
default implementation. - @ryankurte suggested a different transition plan.
This fallible version is only available if both "unproven" and "use-fallible-digital-traits" features are enabled.
I also think the
Thank you both @ryankurte and @hannobraun! |
This is looking good! From my perspective, here's what's left to to get this merged:
|
/// assert!(pin.is_set_low()); | ||
/// #[cfg(feature = "use-fallible-digital-traits")] | ||
/// assert!(pin.is_set_low().unwrap()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I'm wondering, if we should simplify the example. I mean, we want people to use the new fallible versions, so why even show the infallible versions here? Thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the docs should prioritise the fallible version, though maybe we could keep the infallible documentation until the opt-out release?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved the fallible versions up. However, the example still looks quite cluttered with #cfg...
to me. Any ideas?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a bit cluttered, maybe grouping each example would help?
I'm ok with merging this either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found no way to group the statements so that I can have fewer #cfg
s. Do you have an idea?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! Looks excellent. I have commented with a few changes, please let me know if you disagree with any of them.
The only other thing that would be neat is to test / demonstrate that it all works by updating a driver crate, but we can either do that here or once it's landed before we release.
CHANGELOG.md
Outdated
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/). | |||
|
|||
## [Unreleased] | |||
|
|||
### Added | |||
|
|||
- A `FallibleOutputPin` trait has been added. It is a version of the `OutputPin` trait |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs to be updated to match the feature based approach, and we probably need to document that this release is opt-in and the next will be opt-out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
/// assert!(pin.is_set_low()); | ||
/// #[cfg(feature = "use-fallible-digital-traits")] | ||
/// assert!(pin.is_set_low().unwrap()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that the docs should prioritise the fallible version, though maybe we could keep the infallible documentation until the opt-out release?
Ok here is a new version. Please review the points raised and let me know if you want further changes.
Thoughts? |
Ok, I implemented the new traits on my pcf857x I/O expander driver on this branch. |
CHANGELOG.md
Outdated
- Fallible versions of the `OutputPin` and `StatefulOutputPin` traits have been added. | ||
These are versions where the methods return a `Result` type as setting an output pin | ||
could potentially fail. | ||
The current trait versions are now marked as deprecated. The fallible version |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we be marking the new traits with unproven
too? (I'm not sure if there is a precedent, seems ok either way)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
StatefulOutputPin
is already marked as unproven
and its interface will not change if not activating use-fallible-digital-traits
. The only fallible trait one not behind the unproven
feature is the fallible OutputPin
.
Thanks for the excellent work @eldruin! I appreciate your effort in working through these changes with us ^_^ The only niggling worry I have is whether we should be feature gating the unproven traits as well. While there is no guarantee that they don't change, the reality is everyone using it probably builds with the unproven feature on (I know I do) and is going to get hit by the API breakage, somewhat undermining our plan for a smooth transition. I think my preference would be to take the same feature-flag migration approach with the unproven traits, so all the digital traits are feature-flagged one way or the other and marked unproven again. Any thoughts on this @hannobraun? |
Additional info: I took care of changing the code so that it is possible to activate the |
Well, if you think it should be done, and if @eldruin is willing to do it, then I'm fine with that. But honestly, I think it's unnecessary. I we can't change unproven traits, then what is the point of having the flag? New thought: Should we (temporarily) test the new feature flags in the Travis build, or is it enough to test them locally before merging? |
Whoops, pushed the wrong button sorry.
I agree in theory but am not really sure the unproven flag works the way it was intended, maybe when the bulk of the library has stabilised so it's not so compulsory it'll fit better, maybe it'd be better with more granularity (a flag per trait), but that is probably a discussion for another place. If we don't do it, we are causing breakage for the people who do use those traits, but maybe they'll just opt in to the new traits and fix everything then anyway. I can see pros and cons of both and am happy merging either, so, @eldruin up to you. (Regardless of the direction, given the widespread ramifications of changes to this project it'd be neat to have feedback on the release process from users? Maybe we could have a forum post or an issue for release feedback / experiences.)
Ahh, yeah that should probably go into the build matrix, to be changed when we change and eventually remove the flags. |
I agree. I've asked myself a few times what the point of the flag is, given the early state that this library still is in. More granular flags sound like a good idea, and would fit well with what we're doing in this pull request.
I agree. We have an embedded category in u.r-l.o now, which seems like a good place for this kind of thing.
Okay, so I guess this updates the todo list for this pull request as follows:
|
@hannobraun The main problem I see with |
Yes, that certainly doesn't help. |
Ok, just to let you know, I am on vacation and will have a look at this next week :) |
…recated - Add general documentation about transition process to digital module - Update CHANGELOG
Ok I pushed my last local changes but interesting arguments were brought up in #100 so let's settle that first. |
@eldruin Agreed. Best to wait for the result of that discussion. |
Ok, there seems to be some consensus in #100 that this should be implemented as a clean break. I will prepare a new version soon. |
Ok I did not want to squash the commits in this branch in case github makes a mess of the discussion in this PR so I opened #105 with everything in one commit. |
Following the discussion in #95, I have made these changes:
InputPin
trait methods fallible.FallibleOutputPin
trait with fallible versions of theOutputPin
methods.ToggeableOutputPin
trait method fallible.Now, should
StatefulOutputPin
methods also be fallible? I think so, but I was not able to get it to work:In the implementation of
ToggeableOutputPin
for the software-driven toggle (FallibleOutputPin
+StatefulOutputPin
) there are now twoError
types and I do not know how to solve this correctly.You can see precisely what I mean by applying the patch below on top of this branch. If you do so,
the compiler will rightfully complain that the
Error
associated type in bounds ofP
is ambiguous.What do you think?