ohos-ext 0.1.0

ohos ffrt ext for ohos-rs
use futures::Future;
use napi_ohos::{Env, Error, JsValue, Result, SendableResolver, Status, Unknown, sys};
use ohos_ffrt::Runtime;

pub fn spawn_local<
    Data: 'static + Send,
    Fut: 'static + Send + Future<Output = std::result::Result<Data, impl Into<Error>>>,
    Resolver: 'static + FnOnce(sys::napi_env, Data) -> Result<sys::napi_value>,
>(
    env: sys::napi_env,
    fut: Fut,
    resolver: Resolver,
) -> Result<sys::napi_value> {
    let env = Env::from(env);

    let (deferred, promise) = env.create_deferred::<Unknown<'_>, _>()?;

    let deferred_for_panic = deferred.clone();
    let sendable_resolver = SendableResolver::new(resolver);

    let inner = async move {
        match fut.await {
            Ok(v) => deferred.resolve(move |env| {
                sendable_resolver
                    .resolve(env.raw(), v)
                    .map(|v| unsafe { Unknown::from_raw_unchecked(env.raw(), v) })
            }),
            Err(e) => deferred.reject(e.into()),
        }
    };

    let runtime = Runtime::new();

    let jh = runtime.spawn(inner);

    runtime.spawn(async move {
        if let Err(err) = jh.await {
            deferred_for_panic.reject(Error::new(Status::GenericFailure, err.to_string()));
        }
    });

    Ok(promise.raw())
}