Best way to replace an async trait

I'm trying to code a Node structure that can connect to the network using either wasm-code or i586 binary. My first try ended here: https://github.com/rustwasm/wasm-bindgen/issues/2409
My second try was much uglier and longer and includes Closures, but I cannot get it to work, because I have problems with the lifetime of the structures I want to put in the Closure. So if somebody can help me fix that problem, or tell me how to make it more nicely and rusty, either would be really appreciated :wink:

The goal is to have the Node structure accept a RestClient, which will either be implemented for wasm, or for i586 code. I tried to play around with the lifetimes, but as far as I can understand, the rc should have a static lifetime for this to work. But I don't know how to make it so :frowning:

pub async fn start() -> Result<(), JsValue> {
    let rc = RestClient::new("http://localhost:8000");
    // Both of these don't work:
    let mut rs = Node::new(move |p, d| Box::pin(rc.rest(p.to_string(), d.to_string())));
    // Just to check it would work if I get the borrowing on the arguments correct
    let mut rs = Node::new(move |p, d| Box::pin(rc.rest("".to_string(), "".to_string())));
    rs.rest_caller("path", "data").await;
    Ok(())
}

struct Node<'r, F>
where
    F: Fn(String, String) -> Pin<Box<dyn Future<Output = Result<String, String>> + 'r>>,
{
    rest: F,
}

impl<'r, F> Node<'r, F>
where
    F: Fn(String, String) -> Pin<Box<dyn Future<Output = Result<String, String>> + 'r>>,
{
    fn new(rest: F) -> Node<'r, F> {
        Node { rest }
    }

    pub async fn rest_caller(&mut self, path: &str, data: &str) {
        (self.rest)(path.to_string(), data.to_string()).await;
    }
}

struct RestClient {
    base: String,
}

impl RestClient {
    pub fn new(base: &str) -> RestClient {
        RestClient {
            base: base.to_string(),
        }
    }

    pub async fn rest(&self, path: String, _data: String) -> Result<String, String> {
        // Some fancy async stuff happening here
        Ok("".to_string())
    }
}

Seems that this is in fact not needed, as rust-wasm and async_trait do work together:

https://github.com/rustwasm/wasm-bindgen/issues/2409#issuecomment-754574965

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.