Skip to content

set_state and toggle for digital::OutputPin #44

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

Closed
wants to merge 3 commits into from
Closed

set_state and toggle for digital::OutputPin #44

wants to merge 3 commits into from

Conversation

burrbull
Copy link
Member

set_state and toggle with default implementation

set_state and toggle with default implementation
Copy link
Contributor

@therealprof therealprof left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I quite like the set_state() and toggle() methods, especially since the latter is specialisable in case there's hardware toggle support.

Not so happy about the snuck in default implementation for is_high(). IMHO we should rather (in a separate topic because this might be controversial!) add a get_state() function (also for the InputPin) and make is_high() and is_low() be default implementations of the get_state() function. In case of the OutputPin we may even have to make that fallible since it is not on all platforms possible to query the state of output pins (though my memory is faint on which platforms exactly didn't support that).

src/digital.rs Outdated
fn set_high(&mut self);
fn set_high(&mut self) {
!self.is_low()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not look right.

@japaric
Copy link
Member

japaric commented Mar 10, 2018

I personally feel that the get_state methods don't add expressivity to the API. On the contrary,
using them makes the code less readable, IMO:

if pa0.get_state() { // what do you mean by state? input state? output state? floating state?
    // ..
}

if pa0.is_high() { // OTOH, this is totally unambiguous
    // ..
}

Now if get_state returned a State enum then it would make more sense but I feel that a two
variant enum is a bit overkill in this case.

Both get_states get a 👎 from me in their current state.

I'm of the (unpopular) opinion that set_state(bool) decreases readability but I understand that
people want to be able to easily write stuff like pa0.set_state(pa1.is_high()). I personally would
write:

if pa1.is_high() {
    pa0.set_high()
} else {
    pa0.set_low()
}

Yes, it's longer but it's pretty clear what it does.

I give set_state a zero; I'm not opposed to merging it.

toggle gets a 👍 from me


And a remainder: adding methods to a trait is a breaking change unless the methods have a default implementation.

@burrbull
Copy link
Member Author

burrbull commented Mar 10, 2018

Will set_value be better?
Or set_level ?
Or set_bool ?

@therealprof
Copy link
Contributor

@japaric Usually the state represents the current interpretation, i.e. the level while the "state" in your reading is called the mode, sometimes also separated into administrative mode and operational mode.

@wez
Copy link

wez commented Mar 18, 2018

I came here to propose adding a toggle_level method and found this PR.

FWIW, over time I have come to the opinion that boolean input parameters are to be avoided because the intent is not clear. These days I try to prefer using an enum. In this case I would humbly advocate for get_level and set_level methods that return/accept an enum { Low, High } value.

Can we split out the toggle functionality as a separate PR since that one seems not to be controversial and could be accepted ahead of the rest of this discussion?

@therealprof
Copy link
Contributor

@wez I agree with both of your points. However I wanted to add that using a custom enum makes using the methods a bit more tedious to use unless there's an adapter interface mapping the generally accepted true == high relation.

@burrbull burrbull closed this Mar 18, 2018
bors bot added a commit that referenced this pull request Sep 14, 2020
239: Add try_set_state method for OutputPin r=therealprof a=eldruin

This is an implementation of #200 to gather some opinions and so we can either accept it or close the issue.
This was earlier discussed at #44.

I added a conversion from `bool` following the usual convention as well as an `ops::Not` implementation as suggested in #200, which seemed appropriate.

I also added a default implementation for the `try_set_state` method. This bears the question whether a default implementation for `try_set_high()` / `try_set_low()` by using `try_set_state()` would be useful, so that potential implementors can choose to implement less methods.

It should be noted that adding a default implementation for all 3 methods has the somewhat amusing property of generating an endless loop if none is overwritten.

Closes #200 

Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
peckpeck pushed a commit to peckpeck/embedded-hal that referenced this pull request Nov 10, 2022
44: Implement transactional I2C interface and add example r=ryankurte a=eldruin

I implemented the transactional I2C interface from rust-embedded#223 and added an example with a driver which does a combined Write/Read transaction.
This is based on previous work from rust-embedded#33 by @ryankurte, rust-embedded/rust-i2cdev#51 and is similar to rust-embedded#35.

Co-authored-by: Diego Barrios Romero <eldruin@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants