Hey, well I don't have the link to this video but I could imagine that you are referring to a possibility to store the state of a pin as generic with the structure to encode it at compile time.
Something like this (encoding pin function and pull-up/down config):
pub struct Pin<FUNCTION, PUD> {
function: FUNCTION,
pud: PUD,
}
/// Type states for the FUNCTION generic argument of the pin.
pub(crate) mod function {
pub struct Input;
pub struct Output;
pub struct Unknown;
}
/// Type states for the PUD template argument of the pin
pub(crate) mod pud {
pub struct PullDown;
pub struct PullUp;
pub struct Disabled;
pub struct Unknown;
}
/// Functions available for any kind of pin
impl<FUNC, PUD> Pin<FUNC, PUD> {
/// Create a new ``Pin`` with an unknown function and PUD settings.
#[allow(clippy::new_ret_no_self)]
pub fn new(num: u32) -> Pin<function::Unknown, pud::Unknown> {
Pin {
function: function::Unknown,
pud: pud::Unknown,
}
}
/// switch any pin into an input pin
pub fn into_input(self) -> Pin<function::Input, PUD> {
/* do the hardware config */
Pin {
function: function::Input,
pud: self.pud,
}
}
/* implement the other methods accordingly to provide the different pin config's */
}
/// Functions available only for an Output pin with any PUD setting
impl<PUD> Pin<function::Output, PUD> {
pub fn high(&self) {
/* do the register / hardware stuff */
}
pub fn low(&self) {
/* do the register / hardware stuff */
}
}
A function can then be defined to require a specific pin config
fn foo<PUD>(pin: &Pin<function::Output, PUD>) {
pin.high();
}
use this then like this
let pin = Pin::<function::Unknown, pud::Unknown>::new(10).into_input();
foo(&pin);
The above call gives compile error:
63 | foo(&pin);
| ^^^^ expected struct `function::Output`, found struct `function::Input`
|
= note: expected reference `&Pin<function::Output, _>`
found reference `&Pin<function::Input, pud::Unknown>`
as we have passed an input pin where an output pin is expected.
Hope this helps 