RIOT-OS / rust-riot-wrappers

The `riot-wrappers` crate, which enables high-level access to RIOT from the Rust programming language
12 stars 11 forks source link

ZTimer: Input types for `sleep{,_extended}` functions #112

Open chrysn opened 3 weeks ago

chrysn commented 3 weeks ago

Right now (since https://github.com/RIOT-OS/rust-riot-wrappers/issues/66 cleaned up a prior way more inconsistent state), sleep takes Ticks and sleep_extended takes a Duration.

Generally, either could take different kinds of times, eg. fugit types (as previously suggested in https://gitlab.com/etonomy/riot-wrappers/-/issues/6), possibly constructed from helper functions (sleep_seconds(5), sleep_milliseconds(500)). I think the expectation should be that anything accepted by sleep is convertible at build time, whereas sleep_extended may incur relatively costly transformations that may cause multiple sleeps on overflow.

chrysn commented 3 weeks ago

Given fugit allows a lot of constness, we could allow .sleep() to accept ticks or a compatible fugit type. Then, clock_ms.sleep(5.secs()) would should build time converted (but can't be enforced), clock_ms.sleep(Duration::secs(5)) would be too, and clock_ms.sleep(const { Duration::secs(5) }) would make the conversion a build time error (which is otherwise, AIU, a panic inside secs()).

chrysn commented 3 weeks ago

The const doesn't work quite that easily: The type can't be used for easy const construction because there there is also the parameter (u32/u64) which apparently can't be inferred even through a From/Into. Thus, the type needs annotations, and those can't be left incomplete without generic_arg_infer:

#![feature(generic_arg_infer)]
use fugit::ExtU32;

fn main() {
    let t1: T::<100000> = 32.secs().into();
    let t2: T::<100000> = const { fugit::Duration::<u32, _, _>::secs(1000000) }.into();
    println!("Hello, world! {:?}", t1);
    println!("Hello, world! {:?}", t2);
}

#[derive(Debug)]
struct T<const HZ: u32> { ticks: u32 }

impl<const HZ: u32> From<fugit::Duration<u32, 1, HZ>> for T<HZ> {
    fn from(orig: fugit::Duration<u32, 1, HZ>) -> Self {
        Self { ticks: orig.ticks() }
    }
}