use anyhow::Result;
use rusty_v8 as v8;
#[derive(Debug, Clone, PartialEq)]
pub enum PaymentRequestState {
Created, Interactive, Closed, }
pub fn setup_payment_request_api(
scope: &mut v8::ContextScope<v8::HandleScope>,
context: &v8::Local<v8::Context>,
_global: v8::Local<v8::Object>,
) -> Result<()> {
let global = context.global(scope);
let payment_request_fn = v8::FunctionTemplate::new(scope, payment_request_constructor_callback);
let payment_request_constructor = payment_request_fn.get_function(scope).unwrap();
let payment_request_key = v8::String::new(scope, "PaymentRequest").unwrap();
global.set(
scope,
payment_request_key.into(),
payment_request_constructor.into(),
);
let payment_response_fn =
v8::FunctionTemplate::new(scope, payment_response_constructor_callback);
let payment_response_constructor = payment_response_fn.get_function(scope).unwrap();
let payment_response_key = v8::String::new(scope, "PaymentResponse").unwrap();
global.set(
scope,
payment_response_key.into(),
payment_response_constructor.into(),
);
let payment_address_fn = v8::FunctionTemplate::new(scope, payment_address_constructor_callback);
let payment_address_constructor = payment_address_fn.get_function(scope).unwrap();
let payment_address_key = v8::String::new(scope, "PaymentAddress").unwrap();
global.set(
scope,
payment_address_key.into(),
payment_address_constructor.into(),
);
Ok(())
}
fn payment_request_constructor_callback(
scope: &mut v8::PinScope,
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue,
) {
let _method_data = if args.length() > 0 {
args.get(0)
} else {
rv.set(v8::undefined(scope).into());
return;
};
let _details = if args.length() > 1 {
args.get(1)
} else {
v8::undefined(scope).into()
};
let _options = if args.length() > 2 {
args.get(2)
} else {
v8::undefined(scope).into()
};
let pr_obj = v8::Object::new(scope);
let undefined_val: v8::Local<v8::Value> = v8::undefined(scope).into();
let id_key = v8::String::new(scope, "id").unwrap();
let id_val = v8::String::new(scope, "payment-req-12345").unwrap();
pr_obj.set(scope, id_key.into(), id_val.into());
let method_key = v8::String::new(scope, "method").unwrap();
pr_obj.set(scope, method_key.into(), undefined_val);
let shipping_addr_key = v8::String::new(scope, "shippingAddress").unwrap();
pr_obj.set(scope, shipping_addr_key.into(), undefined_val);
let shipping_opt_key = v8::String::new(scope, "shippingOption").unwrap();
pr_obj.set(scope, shipping_opt_key.into(), undefined_val);
let show_fn = v8::FunctionTemplate::new(scope, payment_request_show_callback);
let show_key = v8::String::new(scope, "show").unwrap();
let show_func = show_fn.get_function(scope).unwrap();
pr_obj.set(scope, show_key.into(), show_func.into());
let abort_fn = v8::FunctionTemplate::new(scope, payment_request_abort_callback);
let abort_key = v8::String::new(scope, "abort").unwrap();
let abort_func = abort_fn.get_function(scope).unwrap();
pr_obj.set(scope, abort_key.into(), abort_func.into());
let can_pay_fn = v8::FunctionTemplate::new(scope, payment_request_can_make_payment_callback);
let can_pay_key = v8::String::new(scope, "canMakePayment").unwrap();
let can_pay_func = can_pay_fn.get_function(scope).unwrap();
pr_obj.set(scope, can_pay_key.into(), can_pay_func.into());
rv.set(pr_obj.into());
}
fn payment_request_show_callback(
scope: &mut v8::PinScope,
_args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue,
) {
let resolver = match v8::PromiseResolver::new(scope) {
Some(r) => r,
None => {
let error = v8::String::new(scope, "Failed to create promise resolver").unwrap();
scope.throw_exception(error.into());
return;
}
};
let promise = resolver.get_promise(scope);
rv.set(promise.into());
let message = v8::String::new(scope, "Payment Request is not supported yet").unwrap();
let error = v8::Exception::error(scope, message);
resolver.reject(scope, error);
}
fn payment_request_abort_callback(
scope: &mut v8::PinScope,
_args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue,
) {
let resolver = match v8::PromiseResolver::new(scope) {
Some(r) => r,
None => {
let error = v8::String::new(scope, "Failed to create promise resolver").unwrap();
scope.throw_exception(error.into());
return;
}
};
let promise = resolver.get_promise(scope);
rv.set(promise.into());
let message = v8::String::new(scope, "Payment Request is not supported yet").unwrap();
let error = v8::Exception::error(scope, message);
resolver.reject(scope, error);
}
fn payment_request_can_make_payment_callback(
scope: &mut v8::PinScope,
_args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue,
) {
let resolver = match v8::PromiseResolver::new(scope) {
Some(r) => r,
None => {
let error = v8::String::new(scope, "Failed to create promise resolver").unwrap();
scope.throw_exception(error.into());
return;
}
};
let promise = resolver.get_promise(scope);
rv.set(promise.into());
let can_pay = v8::Boolean::new(scope, false);
resolver.resolve(scope, can_pay.into());
}
fn payment_response_constructor_callback(
scope: &mut v8::PinScope,
_args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue,
) {
let message =
v8::String::new(scope, "PaymentResponse construction is not supported yet").unwrap();
let error = v8::Exception::type_error(scope, message);
scope.throw_exception(error);
rv.set(v8::undefined(scope).into());
}
fn payment_address_constructor_callback(
scope: &mut v8::PinScope,
_args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue,
) {
let message =
v8::String::new(scope, "PaymentAddress construction is not supported yet").unwrap();
let error = v8::Exception::type_error(scope, message);
scope.throw_exception(error);
rv.set(v8::undefined(scope).into());
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_payment_request_state_values() {
assert_eq!(PaymentRequestState::Created as u8, 0);
assert_eq!(PaymentRequestState::Interactive as u8, 1);
assert_eq!(PaymentRequestState::Closed as u8, 2);
}
#[test]
fn test_payment_request_state_ordering() {
assert_eq!(PaymentRequestState::Created as u8, 0);
assert_eq!(PaymentRequestState::Interactive as u8, 1);
assert_eq!(PaymentRequestState::Closed as u8, 2);
}
}