embedded-hal icon indicating copy to clipboard operation
embedded-hal copied to clipboard

Pin methods returning results is extremely unfortunate

Open coffeenotfound opened this issue 2 years ago • 7 comments
trafficstars

Most pin functions (is_high(), set_low(), etc.) return results, which are virtually always infallible, but we are still forced to unwrap them which is a very unfortunate and bad design smell.

I'm not sure if the boat has already sailed (I hope not) but here are two ways I think are pretty good solutions:

Approach 1:

Use GATs (or not use GATs and assume pin output is always bool?) to have return values either be a Result or a value.

pub trait InputPin {
    type Output<T> = T;

    fn is_high(&self) -> Self::Output<bool>;
    fn is_low(&self) -> Self::Output<bool>;
}

Approach 2:

Extract into seperate trait and prefix fallible methods with try_ and make non-prefixed ones infallible

pub trait InputPin: FallibleInputPin<Error = Infallible> {
    type Error;
    fn try_is_high(&self) -> Result<bool, Self::Error>;
    fn try_is_low(&self) -> Result<bool, Self::Error>;
}
// Could also require `FallibleInputPin<Error = Infallible>`
// but I'm not sure if the bang/buck is worth it
pub trait InputPin: FallibleInputPin {
    fn is_high(&self) -> bool;
    fn is_low(&self) -> bool;
}

Overall I prefer approach 1 as it works well and is simple. Approach 2 could be better for highly generic code since it's easier to extract the error type for further composing

coffeenotfound avatar Apr 25 '23 16:04 coffeenotfound