admin管理员组

文章数量:1122846

I'm developing a Tauri application that uses deno_core to run some plugins.

To enable proper communication between them, I want to implement emit and listen methods through ops. The listen method requires an async op, and I'm having trouble accessing OpState in this context.

How can I correctly access OpState? Or are there better practices for communication between Tauri and deno_core?

My code is:

#[op2(async)]
async fn op_tauri_listen(
    state: Rc<OpState>,  // 改回 Rc<OpState>
    #[string] event: String,
) -> Result<(), AnyError> {
    let (sender, receiver) = oneshot::channel::<String>();
    // ...
}

The error is:

error: custom attribute panicked
   --> src/deno.rs:391:1
    |
391 | #[op2(async)]
    | ^^^^^^^^^^^^^
    |
    = help: message: Failed to parse #[op2]:
             - Failed to map signature to V8
             - Unable to map argument Rc(OpState) to a slow argument

I tried to directly access using state: &OpState, but there are lifetime issues:

#[op2(async)]
#[string]
pub async fn op_tauri_emit(
    state: &mut OpState,
    #[string] event: String,
    #[string] payload: Option<String>,
) -> Result<String, AnyError> {
    let context = state.try_borrow::<OpContextState>()
        .ok_or_else(|| AnyError::msg("Failed to get OpContextState"))?;

    let event_id = Uuid::new_v4().to_string();

    let (tx, rx) = oneshot::channel();

    let window = context.window.clone();
    let response_event = format!("response_{}", event_id);
    window.once(&response_event, move |event| {
        let payload = event.payload();
        let _ = tx.send(payload.to_string());
    });

    debug_println!("Event: {:?}", event);
    debug_println!("Event ID: {:?}", event_id);
    debug_println!("Payload: {:?}", payload);

    let emit_payload = serde_json::json!({
        "event_id": event_id,
        "data": payload.unwrap_or_default()
    });

    context.window.emit(&event, emit_payload)
        .map_err(|e| AnyError::msg(format!("Failed to emit event: {}", e)))?;

    match tokio::time::timeout(
        std::time::Duration::from_secs(5),
        rx,
    ).await {
        Ok(channel_result) => {
            match channel_result {
                Ok(response) => Ok(response),
                Err(e) => Err(AnyError::msg(format!("Failed to receive response: {}", e)))
            }
        }
        Err(_) => Err(AnyError::msg("Response timeout"))
    }
}
error: lifetime may not live long enough
   --> src/deno.rs:373:1
    |
373 | #[op2(async)]
    | ^^^^^^^^^^^^^
    | |
    | lifetime `'s` defined here
    | type annotation requires that `'s` must outlive `'static`
    |
    = note: this error originates in the attribute macro `op2` (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0716]: temporary value dropped while borrowed
   --> src/deno.rs:373:1
    |
373 | #[op2(async)]
    | ^^^^^^^^^^^^-
    | |           |
    | |           temporary value is freed at the end of this statement
    | creates a temporary value which is freed while still in use
    | argument requires that borrow lasts for `'static`
    |
    = note: this error originates in the attribute macro `op2` (in Nightly builds, run with -Z macro-backtrace for more info)

本文标签: rustHow to access OpState in async functions when using denocore39s op2Stack Overflow