rust-osdev / volatile

Apache License 2.0
71 stars 19 forks source link

Add `#[derive(VolatileFieldAccess)]` for easy, access-limited field-based access to structs #49

Closed mkroening closed 5 months ago

mkroening commented 5 months ago

This PR adds a new proc-macro that adds additional functions to VolatilePtr for user-defined types, with support for access-limitations.

This means this code

#[repr(C)]
#[derive(Volatile)]
pub struct DeviceConfig {
    feature_select: u32,
    #[access(ReadOnly)]
    feature: u32,
}

will derive this code:

pub trait DeviceConfigVolatile<'a> {
    fn feature_select(self) -> VolatilePtr<'a, u32, ReadWrite>;

    fn feature(self) -> VolatilePtr<'a, u32, ReadOnly>;
}

impl<'a> DeviceConfigVolatile<'a> for VolatilePtr<'a, DeviceConfig, ReadWrite> {
    fn feature_select(self) -> VolatilePtr<'a, u32, ReadWrite> {
        map_field!(self.feature_select).restrict()
    }

    fn feature(self) -> VolatilePtr<'a, u32, ReadOnly> {
        map_field!(self.feature).restrict()
    }
}

My motivation for this is that I found map_field! not ideal to use when your field is nested (map_field!(one.two.three) does not work) and it does not chain well (cannot be nested). Additionally, this proc-macro allows you to properly specify access restrictions for your fields.

I thought this would be a nice fit for this repository rather than publishing the crate independently, for visibility, discoverability, and maintenance. What are your thoughts on this?

This PR depends on https://github.com/rust-osdev/volatile/pull/47

mkroening commented 5 months ago

I have also slightly refactored the macro implementation (parsing into one struct instead of many) and have made the macro copy the docs from struct to trait.

phil-opp commented 5 months ago

Thanks a lot!

Should I create a new release or do you have other changes planned that we should wait for?

mkroening commented 5 months ago

Should I create a new release or do you have other changes planned that we should wait for?

I just opened https://github.com/rust-osdev/volatile/pull/51 and https://github.com/rust-osdev/volatile/pull/52, but they are not urgent. Apart from that, this should be good to go. Thanks a lot! :)