|
| 1 | +- Feature Name: digital_v3 |
| 2 | +- Start Date: 2019-11-17 |
| 3 | +- RFC PR: (leave this empty) |
| 4 | +- Rust Issue: (leave this empty) |
| 5 | + |
| 6 | +# Summary |
| 7 | +[summary]: #summary |
| 8 | + |
| 9 | +This RFC proposes `digital::v3` fallible interface and un-deprecation of `digital::v1` interface. |
| 10 | + |
| 11 | +# Motivation |
| 12 | +[motivation]: #motivation |
| 13 | + |
| 14 | +Current `digital::v2` interface has some problems: |
| 15 | + |
| 16 | +* `digital::v2` interface has the same method names as `digital::v1` interface, |
| 17 | +due to this fact they cannot be used together and `digital::v2` traits in prelude may break things. |
| 18 | +* Current implementation deprecates `digital::v1` in favor of `digital::v2` interface, |
| 19 | +this has unforeseen consequences for HAL libraries. |
| 20 | +As a result, user code suffers from useless `.unwrap()` constructions. |
| 21 | + |
| 22 | +This RFC aims to solve these problems. |
| 23 | + |
| 24 | +Currently, `embedded-hal` digital traits are used from three perspectives: |
| 25 | +* driver developers |
| 26 | +* hal developers |
| 27 | +* end-users |
| 28 | + |
| 29 | +`digital::v2` traits were introduced to provide driver developers with a way to work with |
| 30 | +potentially fallible GPIO pins. Such pins can be created by drivers for external GPIO expanders connected |
| 31 | +via fallible peripherals (e.g. i2c). At the same time, most MCUs do not have fallible GPIOs and hals are not |
| 32 | +required to implement fallible `digital::v2` interface for them. |
| 33 | + |
| 34 | +Due to the deprecation of `digital::v1` traits, hal maintainers were annoyed by deprecation warnings and |
| 35 | +switched to `digital::v2` traits to get rid of these warnings. This change introduced another problem: |
| 36 | +end-users started getting warnings about unused result for the new (now `digital::v2`) GPIO methods. |
| 37 | +These warnings introduced the `.unwrap()` pattern for using GPIO methods, even for GPIOs provided by MCU hal |
| 38 | +libraries. Since most embedded projects do not use external fallible GPIOs, this led to |
| 39 | +a decrease in code readability. |
| 40 | + |
| 41 | +From the end-user perspective, co-existence of `digital::v2` and `digital::v1` traits led to another problem: |
| 42 | +since all `digital::v1` implicitly implement `digital::v2` traits, they implement two different |
| 43 | +traits with the same method names. When both traits are in scope, calls to any of the `digital::v1` methods |
| 44 | +produce an error due to the ambiguity of used trait. Due to this fact, one also can't have both traits in |
| 45 | +`embedded-hal` prelude for convenience. |
| 46 | + |
| 47 | +# Detailed design |
| 48 | +[design]: #detailed-design |
| 49 | + |
| 50 | +This RFC proposes the following changes: |
| 51 | + |
| 52 | +* Add `digital::v3` interface with the same traits as `digital::v2`, but with methods named with `try_` prefix. |
| 53 | +For example, `ToggleableOutputPin` will have `try_toggle` method instead of `toggle`. |
| 54 | +* Provide transparent conversion from `digital::v2` traits to `digital::v3` traits. |
| 55 | +* Change `digital::v1` compatibility layer to convert from `digital::v3` traits instead of `digital::v2` ones. |
| 56 | +* Add `V2OutputPin` proxy to the `digital::v2` compatibility layer to provide `digital::v3` -> `digital::v2` downgrade. |
| 57 | +* Add `digital::v3` traits to prelude. |
| 58 | +* Un-deprecate `digital::v1` traits, add a note for driver developers. |
| 59 | +* Deprecate `digital::v2` traits in favor of `digital::v3` traits. |
| 60 | +* Move HALs back to `digital::v1` interface. |
| 61 | + |
| 62 | +### Consequences |
| 63 | + |
| 64 | +* End users will be able to use both fallible and infallible traits and import them via `embedded-hal` prelude. |
| 65 | +* HALs will export GPIOs as infallible (as they really are). |
| 66 | +* Driver developers can move to fallible `digital::v3` traits with minimal effort. |
| 67 | +* End users that use drivers with `digital::v2` interface will continue using them without any changes in |
| 68 | +most of the cases. Newer `digital::v3` objects could be passed to `digital::v2` consumers via `V2OutputPin` shim. |
| 69 | + |
| 70 | +# How We Teach This |
| 71 | +[how-we-teach-this]: #how-we-teach-this |
| 72 | + |
| 73 | + |
| 74 | + |
| 75 | +What names and terminology work best for these concepts and why? |
| 76 | +How is this idea best presented—as a continuation of existing Rust patterns, or as a wholly new one? |
| 77 | + |
| 78 | +Would the acceptance of this proposal change how Rust is taught to new users at any level? |
| 79 | +How should this feature be introduced and taught to existing Rust users? |
| 80 | + |
| 81 | +What additions or changes to the Rust Reference, _The Rust Programming Language_, and/or _Rust by Example_ does it entail? |
| 82 | + |
| 83 | +# Drawbacks |
| 84 | +[drawbacks]: #drawbacks |
| 85 | + |
| 86 | +The proposed approach does not provide hal and driver developers with a warning about the interface they should use. |
| 87 | + |
| 88 | +# Alternatives |
| 89 | +[alternatives]: #alternatives |
| 90 | + |
| 91 | +Changing `digital::v2` interface to provide different method names in all the pin traits. |
| 92 | +This solves the name clashing problem, but does not solve `digital::v1` deprecation problem. |
| 93 | + |
| 94 | +# Unresolved questions |
| 95 | +[unresolved]: #unresolved-questions |
| 96 | + |
| 97 | +Naming the methods: while `try_set_high` and `try_toggle` seem ok, `try_is_set_high` name is a bit weird. |
0 commit comments