Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditionally async Peripheral traits #185

Open
5 tasks
rrbutani opened this issue Jul 28, 2022 · 0 comments
Open
5 tasks

Conditionally async Peripheral traits #185

rrbutani opened this issue Jul 28, 2022 · 0 comments
Assignees
Labels
✨ feature New things! P-low Low priority T-peripheral traits Topic: Peripheral Traits T-wasm Topic: WASM support

Comments

@rrbutani
Copy link
Member

what

In the same vein as #184, when running in the browser, we want to be able to use web APIs that happen to be async to implement some of our peripheral traits. This is not something we can do today because the peripheral traits (and everything above them like the interpreter, the simulator, and Control) are not async.

We should use the approach described in #184 to make these traits async when compiling for the web (wasm).

#[async_trait] (and by extension the async_on_wasm macro described in #184) compose well with the delegate proc macros from [ambassador] that are proposed as a replacement for peripheral_trait! { ... } in #179; i.e. this:

#[async_on_wasm]
#[delegatable_trait]
pub trait Gpio {
    async fn out(&mut self, val: u8) -> Result<(), ()>;
    async fn inp(&mut self) -> Result<u8, ()>;
}

#[derive(Delegate)]
#[delegate(Gpio)]
pub struct GpioWrapper<G: Gpio> {
    gpio: G,
}

works fine. This way this works (on wasm) is that the async_trait macro expands first, rewriting the trait into something that looks like this:

#[delegatable_trait]
pub trait Gpio {
    #[must_use]
    #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
    fn out<'life0, 'async_trait>(
        &'life0 mut self,
        val: u8,
    ) -> ::core::pin::Pin<
        Box<
            dyn ::core::future::Future<Output = Result<(), ()>>
                + ::core::marker::Send
                + 'async_trait,
        >,
    >
    where
        'life0: 'async_trait,
        Self: 'async_trait;
    #[must_use]
    #[allow(clippy::type_complexity, clippy::type_repetition_in_bounds)]
    fn inp<'life0, 'async_trait>(
        &'life0 mut self,
    ) -> ::core::pin::Pin<
        Box<
            dyn ::core::future::Future<Output = Result<u8, ()>>
                + ::core::marker::Send
                + 'async_trait,
        >,
    >
    where
        'life0: 'async_trait,
        Self: 'async_trait;
}

The delegate macro then uses the above as the trait definition and as the template for its delegated implementation. It then produces implementations that look like this:

impl<G: Gpio> Gpio for GpioWrapper<G>
where
    G: Gpio,
{
    fn out<'life0, 'async_trait>(
        &'life0 mut self,
        val: u8,
    ) -> ::core::pin::Pin<
        Box<
            dyn ::core::future::Future<Output = Result<(), ()>>
                + ::core::marker::Send
                + 'async_trait,
        >,
    >
    where
        'life0: 'async_trait,
        Self: 'async_trait,
    {
        self.gpio.out(val)
    }
    fn inp<'life0, 'async_trait>(
        &'life0 mut self,
    ) -> ::core::pin::Pin<
        Box<
            dyn ::core::future::Future<Output = Result<u8, ()>>
                + ::core::marker::Send
                + 'async_trait,
        >,
    >
    where
        'life0: 'async_trait,
        Self: 'async_trait,
    {
        self.gpio.inp()
    }
}

On non-wasm platforms, the async_on_wasm attribute just strips out all of the asyncs and awaits from the trait definition and then lets the delegate macro operate as normal.

Note that reversing the order of the attributes on _ does not work though, as you'd expect.

steps

  • this is blocked on Drop the peripheral_trait! macro #179
  • add async_on_wasm to the peripheral traits
  • rewrite the shims to use async, as required, filling in stubs for the WASM implementations (making issues to fill them in later)
  • annotate things in baseline-sim with async_on_wasm and async/await as necessary
  • ...

where

branch: feat/async-everywhere

open questions

@rrbutani rrbutani added ✨ feature New things! P-low Low priority T-peripheral traits Topic: Peripheral Traits T-wasm Topic: WASM support labels Jul 28, 2022
@rrbutani rrbutani self-assigned this Jul 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ feature New things! P-low Low priority T-peripheral traits Topic: Peripheral Traits T-wasm Topic: WASM support
Projects
None yet
Development

No branches or pull requests

1 participant