Just finished chapter 10 of the Rust book and I thought I’d try digging into some real code. I’m a rust noob, but I’ve got 15 years with embedded C.

I’m working my way through the source code of the stm32l0xx-hal crate. Inside adc.rs on line 96, an implementation for the Adc struct is created for the type Adc<Ready> where Ready is defined on line 324.

/// Analog to Digital converter interface
pub struct Adc<State> {
    rb: ADC,
    sample_time: SampleTime,
    align: Align,
    precision: Precision,
    _state: State,
}

impl Adc<Ready> {
    pub fn new(adc: ADC, rcc: &mut Rcc) -> Self {
        // Enable ADC clocks
        ADC::enable(rcc);
        adc.cr.modify(|_, w| w.advregen().set_bit());

        Self {
            rb: adc,
            sample_time: SampleTime::T_1_5,
            align: Align::Right,
            precision: Precision::B_12,
            _state: Ready,
        }
    }
...
}
...
/// Indicates that the ADC peripheral is ready
pub struct Ready;

I’m a little confused about how the associated function new() works. I understand that it generates a new Adc<Ready>, but I don’t fully understand why it’s inside the impl Adc<Ready> block.

It’s not a method that would be called on an Adc<Ready> type, and it doesn’t take any arguments of type Ready. Couldn’t it just as easily have been inside a impl<T> Adc<T> block?

Or is it that impl types go both ways. Like you can’t return an Adc<Ready> unless you’re inside an impl Adc<Ready>?

Sidenote: Since the Ready struct has no fields, does “Ready” actually create a new instance of a Ready type? (like you don’t need Ready{}?)

  • ch00f@lemmy.worldOP
    link
    fedilink
    English
    arrow-up
    2
    ·
    2 months ago

    You only need this amount of nuance, if you’re designing library APIs for others to use

    Maybe I bit off a lot in my first foray, but my ultimate goal is to write a driver for the segment LCD controller in this chip. I have a very simple project already written in C that uses it, and I’d like to try getting it working in embedded Rust. There isn’t much nuance to the controller (just setting a few register values), so it’ll likely be simpler than the ADC, but I’m digging into the existing drivers for some guidance.

    • Ephera@lemmy.ml
      link
      fedilink
      English
      arrow-up
      1
      ·
      2 months ago

      Yeah, I mean, you’ve got previous programming experience. You evidently know that you’re tackling a harder problem and probably know when to step back and try an easier problem first, if it becomes too frustrating. I just wanted to give a bit of context, so that you know it’s more exotic knowledge, because that’s not always going to be obvious when learning a new language…