Rust on Particle: development discussion

Cool idea here! I've been itching to get into rust, but haven't found a good project yet. So please take my contribution here with a grain of salt-of-inexperience

Edit: I see the same principle was already suggested on the github issue:

Regarding Zach's ideas:

From my rust-research so far, the idiomatic way to do this seems to be to use lifetimes and ownership.
The entire "pinmode" hassle is conceptually orthogonal because it's global mutable state.

The rust-way as I understand it so far would have a "guard object" claim ownership of and wrap around the contended resource. My inspiration here is a variable wrapped by a Mutex lock.
The variable inside is only reachable via mutex.acquire(), and as long as that borrow'd result is in scope, other acquires are impossible.

We'd need marker Traits (similar to Send, Sized, Sync, etc) for DigitalInputPin, DigitalOutputPin, AnalogInputPin, PwmPin, etc.

Suggestion in pseudo code typed on a phone keyboard(sorry in advance for any typo's):

board.rs:

struct D7 {};
struct A0 {};

impl DigitalInputPin for D7;
Impl DigitalOutputPin for D7;
Impl AnalogOutputPin for A0;

MyProgram.rs

{
let outputPin = IO::digitalOut(board::D7);  // claims ownership of D7 marker struct, preventing repeated init
outputPin.setHigh(); // statically guaranteed to work, because setHigh method is only available on correct guard object
outputPin.setLow();

// compile error: D7 no longer owned here:
let failedAttempt = IO::digitalIn(D7);
// compile error: D7 doesn't impl AnalogInputPin
let anotherFailedAttempt = IO::analogOutputPulldown(D7);
} // output pin leaves scope, implicit release of D7
{
let secondTry = IO::digitalIn(board::D7);
let pinValue : bool = secondTry.read(); // maybe "pinvalue : IO:pinOutput" enumtype?
}

By only impl'ing the modes a given pin supports, you statically prevent setting a pin to the wrong pinmode, anything else would trigger type-errors on the function call to init the guard.

1 Like