use core::ops::{AsyncFnOnce, Deref, DerefMut};
use crate::JsValue;
use crate::encode::BinaryDecode;
use crate::ipc::{DecodeError, DecodedData};
pub use crate::encode::{Anchored, ArgAbi, BorrowScope, CallScoped};
use super::{JsCastAnchor, OwnedArgAnchor, RefArg, RefMutArg};
#[doc(hidden)]
pub fn __wry_project_ref_async<G, R, F>(guard: G, with: F) -> impl core::future::Future<Output = R>
where
G: Deref,
F: for<'a> AsyncFnOnce(&'a G::Target) -> R,
{
async move { with(&*guard).await }
}
impl ArgAbi<CallScoped> for &JsValue {
type Wire = RefArg<JsValue>;
type Guard = JsCastAnchor<JsValue>;
type ProjectedGuard = ();
type Projected<'a> = &'a JsValue;
fn decode(_decoder: &mut DecodedData) -> Result<Self::Guard, DecodeError> {
Ok(JsCastAnchor::next_borrowed())
}
fn project<R, F>(guard: Self::Guard, with: F) -> (R, Self::ProjectedGuard)
where
F: for<'a> FnOnce(Self::Projected<'a>) -> R,
{
let result = with(&guard);
(result, ())
}
async fn project_async<R, F>(guard: Self::Guard, with: F) -> R
where
F: for<'a> AsyncFnOnce(Self::Projected<'a>) -> R,
{
with(&guard).await
}
}
impl ArgAbi<Anchored> for &JsValue {
type Wire = JsValue;
type Guard = OwnedArgAnchor<JsValue>;
type ProjectedGuard = Self::Guard;
type Projected<'a> = &'a JsValue;
fn decode(decoder: &mut DecodedData) -> Result<Self::Guard, DecodeError> {
Ok(OwnedArgAnchor::from_value(
<JsValue as BinaryDecode>::decode(decoder)?,
))
}
fn project<R, F>(guard: Self::Guard, with: F) -> (R, Self::ProjectedGuard)
where
F: for<'a> FnOnce(Self::Projected<'a>) -> R,
{
let result = with(&guard);
(result, guard)
}
async fn project_async<R, F>(guard: Self::Guard, with: F) -> R
where
F: for<'a> AsyncFnOnce(Self::Projected<'a>) -> R,
{
with(&guard).await
}
}
impl<S: BorrowScope> ArgAbi<S> for &mut JsValue {
type Wire = RefMutArg<JsValue>;
type Guard = OwnedArgAnchor<JsValue>;
type ProjectedGuard = Self::Guard;
type Projected<'a> = &'a mut JsValue;
fn decode(decoder: &mut DecodedData) -> Result<Self::Guard, DecodeError> {
Ok(OwnedArgAnchor::from_value(
<JsValue as BinaryDecode>::decode(decoder)?,
))
}
fn project<R, F>(mut guard: Self::Guard, with: F) -> (R, Self::ProjectedGuard)
where
F: for<'a> FnOnce(Self::Projected<'a>) -> R,
{
let result = with(guard.deref_mut());
(result, guard)
}
async fn project_async<R, F>(mut guard: Self::Guard, with: F) -> R
where
F: for<'a> AsyncFnOnce(Self::Projected<'a>) -> R,
{
with(guard.deref_mut()).await
}
}