Шаблон стану типу

#[entry]
fn main() -> ! {
    let p = Peripherals::take().unwrap();
    let gpio0 = p0::Parts::new(p.P0);

    let pin: P0_01<Disconnected> = gpio0.p0_01;

    // let gpio0_01_again = gpio0.p0_01; // Помилка, переміщено.
    let mut pin_input: P0_01<Input<Floating>> = pin.into_floating_input();
    if pin_input.is_high().unwrap() {
        // ...
    }
    let mut pin_output: P0_01<Output<OpenDrain>> = pin_input
        .into_open_drain_output(OpenDrainConfig::Disconnect0Standard1, Level::Low);
    pin_output.set_high().unwrap();
    // pin_input.is_high(); // Помилка, переміщено.

    let _pin2: P0_02<Output<OpenDrain>> = gpio0
        .p0_02
        .into_open_drain_output(OpenDrainConfig::Disconnect0Standard1, Level::Low);
    let _pin3: P0_03<Output<PushPull>> =
        gpio0.p0_03.into_push_pull_output(Level::Low);

    loop {}
}
  • Піни не реалізують Copy або Clone, тому може існувати лише один екземпляр кожного з них. Після того, як пін буде переміщено зі структури порту, ніхто інший не зможе його взяти.
  • Зміна конфігурації піна поглинає старий екземпляр піна, тому ви не можете продовжувати використовувати старий екземпляр після цього.
  • Тип значення вказує на стан, у якому воно перебуває: наприклад, у цьому випадку це стан конфігурації піна GPIO. Це кодує машину станів у систему типів і гарантує, що ви не спробуєте використати пін певним чином, не налаштувавши його належним чином. Незаконні переходи станів перехоплюються під час компіляції.
  • Ви можете викликати is_high на вхідному піні та set_high на вихідному піні, але не навпаки.
  • Багато крейтів HAL дотримуються цієї моделі.