[oden] Grab my incomplete QuickJS wrapper
This commit is contained in:
parent
aa70df41a3
commit
898b1fe129
114 changed files with 244181 additions and 0 deletions
191
oden-js/src/conversion/function.rs
Normal file
191
oden-js/src/conversion/function.rs
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
use super::{TryFromValue, TryIntoValue};
|
||||
use crate::{ContextRef, Error, ValueRef, ValueResult};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub trait IntoRustFunctionResult<'r> {
|
||||
fn into_res(self, ctx: &ContextRef<'r>) -> ValueResult<'r>;
|
||||
}
|
||||
|
||||
impl<'r, T: TryIntoValue<'r>> IntoRustFunctionResult<'r> for T {
|
||||
fn into_res(self, ctx: &ContextRef<'r>) -> ValueResult<'r> {
|
||||
self.try_into_value(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, T: TryIntoValue<'r>, E: std::fmt::Display> IntoRustFunctionResult<'r>
|
||||
for core::result::Result<T, E>
|
||||
{
|
||||
fn into_res(self, ctx: &ContextRef<'r>) -> ValueResult<'r> {
|
||||
match self {
|
||||
Ok(v) => v.try_into_value(ctx),
|
||||
Err(e) => Err(Error::RustFunctionError(e.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait RustFunction<'r, F> {
|
||||
fn argument_count() -> usize;
|
||||
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r>;
|
||||
}
|
||||
|
||||
impl<'r, R, F> RustFunction<'r, PhantomData<(&R, &F)>> for F
|
||||
where
|
||||
R: IntoRustFunctionResult<'r>,
|
||||
F: Fn(&ContextRef<'r>) -> R + Sized,
|
||||
{
|
||||
fn argument_count() -> usize {
|
||||
0
|
||||
}
|
||||
|
||||
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r> {
|
||||
if args.len() != 0 {
|
||||
return Err(Error::ArgumentCountMismatch {
|
||||
expected: Self::argument_count(),
|
||||
received: args.len(),
|
||||
});
|
||||
}
|
||||
|
||||
let res = self(context);
|
||||
res.into_res(context)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, R, A, F> RustFunction<'r, PhantomData<(&R, &A, &F)>> for F
|
||||
where
|
||||
R: IntoRustFunctionResult<'r>,
|
||||
A: TryFromValue,
|
||||
F: Fn(&ContextRef<'r>, A) -> R + Sized,
|
||||
{
|
||||
fn argument_count() -> usize {
|
||||
1
|
||||
}
|
||||
|
||||
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r> {
|
||||
if args.len() != Self::argument_count() {
|
||||
return Err(Error::ArgumentCountMismatch {
|
||||
expected: Self::argument_count(),
|
||||
received: args.len(),
|
||||
});
|
||||
}
|
||||
|
||||
let va = A::try_from_value(args[0], &context)?;
|
||||
let res = self(context, va);
|
||||
res.into_res(context)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, R, A, B, F> RustFunction<'r, PhantomData<(&R, &A, &B, &F)>> for F
|
||||
where
|
||||
R: IntoRustFunctionResult<'r>,
|
||||
A: TryFromValue,
|
||||
B: TryFromValue,
|
||||
F: Fn(&ContextRef<'r>, A, B) -> R + Sized,
|
||||
{
|
||||
fn argument_count() -> usize {
|
||||
2
|
||||
}
|
||||
|
||||
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r> {
|
||||
if args.len() != Self::argument_count() {
|
||||
return Err(Error::ArgumentCountMismatch {
|
||||
expected: Self::argument_count(),
|
||||
received: args.len(),
|
||||
});
|
||||
}
|
||||
|
||||
let va = A::try_from_value(args[0], &context)?;
|
||||
let vb = B::try_from_value(args[1], &context)?;
|
||||
let res = self(context, va, vb);
|
||||
res.into_res(context)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, R, A, B, C, F> RustFunction<'r, PhantomData<(&R, &A, &B, &C, &F)>> for F
|
||||
where
|
||||
R: IntoRustFunctionResult<'r>,
|
||||
A: TryFromValue,
|
||||
B: TryFromValue,
|
||||
C: TryFromValue,
|
||||
F: Fn(&ContextRef<'r>, A, B, C) -> R + Sized,
|
||||
{
|
||||
fn argument_count() -> usize {
|
||||
3
|
||||
}
|
||||
|
||||
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r> {
|
||||
if args.len() != Self::argument_count() {
|
||||
return Err(Error::ArgumentCountMismatch {
|
||||
expected: Self::argument_count(),
|
||||
received: args.len(),
|
||||
});
|
||||
}
|
||||
|
||||
let va = A::try_from_value(args[0], &context)?;
|
||||
let vb = B::try_from_value(args[1], &context)?;
|
||||
let vc = C::try_from_value(args[2], &context)?;
|
||||
let res = self(context, va, vb, vc);
|
||||
res.into_res(context)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, R, A, B, C, D, F> RustFunction<'r, PhantomData<(&R, &A, &B, &C, &D, &F)>> for F
|
||||
where
|
||||
R: IntoRustFunctionResult<'r>,
|
||||
A: TryFromValue,
|
||||
B: TryFromValue,
|
||||
C: TryFromValue,
|
||||
D: TryFromValue,
|
||||
F: Fn(&ContextRef<'r>, A, B, C, D) -> R + Sized,
|
||||
{
|
||||
fn argument_count() -> usize {
|
||||
4
|
||||
}
|
||||
|
||||
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r> {
|
||||
if args.len() != Self::argument_count() {
|
||||
return Err(Error::ArgumentCountMismatch {
|
||||
expected: Self::argument_count(),
|
||||
received: args.len(),
|
||||
});
|
||||
}
|
||||
|
||||
let va = A::try_from_value(args[0], &context)?;
|
||||
let vb = B::try_from_value(args[1], &context)?;
|
||||
let vc = C::try_from_value(args[2], &context)?;
|
||||
let vd = D::try_from_value(args[3], &context)?;
|
||||
let res = self(context, va, vb, vc, vd);
|
||||
res.into_res(context)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r, R, A, B, C, D, E, F> RustFunction<'r, PhantomData<(&R, &A, &B, &C, &D, &E, &F)>> for F
|
||||
where
|
||||
R: IntoRustFunctionResult<'r>,
|
||||
A: TryFromValue,
|
||||
B: TryFromValue,
|
||||
C: TryFromValue,
|
||||
D: TryFromValue,
|
||||
E: TryFromValue,
|
||||
F: Fn(&ContextRef<'r>, A, B, C, D, E) -> R + Sized,
|
||||
{
|
||||
fn argument_count() -> usize {
|
||||
5
|
||||
}
|
||||
|
||||
fn call(&self, context: &ContextRef<'r>, args: &[&ValueRef<'r>]) -> ValueResult<'r> {
|
||||
if args.len() != Self::argument_count() {
|
||||
return Err(Error::ArgumentCountMismatch {
|
||||
expected: Self::argument_count(),
|
||||
received: args.len(),
|
||||
});
|
||||
}
|
||||
|
||||
let va = A::try_from_value(args[0], &context)?;
|
||||
let vb = B::try_from_value(args[1], &context)?;
|
||||
let vc = C::try_from_value(args[2], &context)?;
|
||||
let vd = D::try_from_value(args[3], &context)?;
|
||||
let ve = E::try_from_value(args[4], &context)?;
|
||||
let res = self(context, va, vb, vc, vd, ve);
|
||||
res.into_res(context)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue