use crate::{CheckSyntaxMode, CheckSyntaxResult, Exception, Value, VirtualMachine};
use glib::{prelude::*, translate::*};
use std::boxed::Box as Box_;
glib::wrapper! {
#[doc(alias = "JSCContext")]
pub struct Context(Object<ffi::JSCContext, ffi::JSCContextClass>);
match fn {
type_ => || ffi::jsc_context_get_type(),
}
}
impl Context {
pub const NONE: Option<&'static Context> = None;
#[doc(alias = "jsc_context_new")]
pub fn new() -> Context {
unsafe { from_glib_full(ffi::jsc_context_new()) }
}
#[doc(alias = "jsc_context_new_with_virtual_machine")]
#[doc(alias = "new_with_virtual_machine")]
pub fn with_virtual_machine(vm: &impl IsA<VirtualMachine>) -> Context {
unsafe {
from_glib_full(ffi::jsc_context_new_with_virtual_machine(
vm.as_ref().to_glib_none().0,
))
}
}
pub fn builder() -> ContextBuilder {
ContextBuilder::new()
}
#[doc(alias = "jsc_context_get_current")]
#[doc(alias = "get_current")]
pub fn current() -> Option<Context> {
unsafe { from_glib_none(ffi::jsc_context_get_current()) }
}
}
impl Default for Context {
fn default() -> Self {
Self::new()
}
}
#[must_use = "The builder must be built to be used"]
pub struct ContextBuilder {
builder: glib::object::ObjectBuilder<'static, Context>,
}
impl ContextBuilder {
fn new() -> Self {
Self {
builder: glib::object::Object::builder(),
}
}
pub fn virtual_machine(self, virtual_machine: &impl IsA<VirtualMachine>) -> Self {
Self {
builder: self
.builder
.property("virtual-machine", virtual_machine.clone().upcast()),
}
}
#[must_use = "Building the object from the builder is usually expensive and is not expected to have side effects"]
pub fn build(self) -> Context {
self.builder.build()
}
}
mod sealed {
pub trait Sealed {}
impl<T: super::IsA<super::Context>> Sealed for T {}
}
pub trait ContextExt: IsA<Context> + sealed::Sealed + 'static {
#[doc(alias = "jsc_context_check_syntax")]
fn check_syntax(
&self,
code: &str,
mode: CheckSyntaxMode,
uri: &str,
line_number: u32,
) -> (CheckSyntaxResult, Exception) {
let length = code.len() as _;
unsafe {
let mut exception = std::ptr::null_mut();
let ret = from_glib(ffi::jsc_context_check_syntax(
self.as_ref().to_glib_none().0,
code.to_glib_none().0,
length,
mode.into_glib(),
uri.to_glib_none().0,
line_number,
&mut exception,
));
(ret, from_glib_full(exception))
}
}
#[doc(alias = "jsc_context_clear_exception")]
fn clear_exception(&self) {
unsafe {
ffi::jsc_context_clear_exception(self.as_ref().to_glib_none().0);
}
}
#[doc(alias = "jsc_context_evaluate")]
fn evaluate(&self, code: &str) -> Option<Value> {
let length = code.len() as _;
unsafe {
from_glib_full(ffi::jsc_context_evaluate(
self.as_ref().to_glib_none().0,
code.to_glib_none().0,
length,
))
}
}
#[doc(alias = "jsc_context_evaluate_with_source_uri")]
fn evaluate_with_source_uri(&self, code: &str, uri: &str, line_number: u32) -> Option<Value> {
let length = code.len() as _;
unsafe {
from_glib_full(ffi::jsc_context_evaluate_with_source_uri(
self.as_ref().to_glib_none().0,
code.to_glib_none().0,
length,
uri.to_glib_none().0,
line_number,
))
}
}
#[doc(alias = "jsc_context_get_exception")]
#[doc(alias = "get_exception")]
fn exception(&self) -> Option<Exception> {
unsafe {
from_glib_none(ffi::jsc_context_get_exception(
self.as_ref().to_glib_none().0,
))
}
}
#[doc(alias = "jsc_context_get_global_object")]
#[doc(alias = "get_global_object")]
fn global_object(&self) -> Option<Value> {
unsafe {
from_glib_full(ffi::jsc_context_get_global_object(
self.as_ref().to_glib_none().0,
))
}
}
#[doc(alias = "jsc_context_get_value")]
#[doc(alias = "get_value")]
fn value(&self, name: &str) -> Option<Value> {
unsafe {
from_glib_full(ffi::jsc_context_get_value(
self.as_ref().to_glib_none().0,
name.to_glib_none().0,
))
}
}
#[doc(alias = "jsc_context_get_virtual_machine")]
#[doc(alias = "get_virtual_machine")]
fn virtual_machine(&self) -> Option<VirtualMachine> {
unsafe {
from_glib_none(ffi::jsc_context_get_virtual_machine(
self.as_ref().to_glib_none().0,
))
}
}
#[doc(alias = "jsc_context_pop_exception_handler")]
fn pop_exception_handler(&self) {
unsafe {
ffi::jsc_context_pop_exception_handler(self.as_ref().to_glib_none().0);
}
}
#[doc(alias = "jsc_context_push_exception_handler")]
fn push_exception_handler<P: Fn(&Context, &Exception) + 'static>(&self, handler: P) {
let handler_data: Box_<P> = Box_::new(handler);
unsafe extern "C" fn handler_func<P: Fn(&Context, &Exception) + 'static>(
context: *mut ffi::JSCContext,
exception: *mut ffi::JSCException,
user_data: glib::ffi::gpointer,
) {
let context = from_glib_borrow(context);
let exception = from_glib_borrow(exception);
let callback: &P = &*(user_data as *mut _);
(*callback)(&context, &exception)
}
let handler = Some(handler_func::<P> as _);
unsafe extern "C" fn destroy_notify_func<P: Fn(&Context, &Exception) + 'static>(
data: glib::ffi::gpointer,
) {
let _callback: Box_<P> = Box_::from_raw(data as *mut _);
}
let destroy_call3 = Some(destroy_notify_func::<P> as _);
let super_callback0: Box_<P> = handler_data;
unsafe {
ffi::jsc_context_push_exception_handler(
self.as_ref().to_glib_none().0,
handler,
Box_::into_raw(super_callback0) as *mut _,
destroy_call3,
);
}
}
#[doc(alias = "jsc_context_set_value")]
fn set_value(&self, name: &str, value: &impl IsA<Value>) {
unsafe {
ffi::jsc_context_set_value(
self.as_ref().to_glib_none().0,
name.to_glib_none().0,
value.as_ref().to_glib_none().0,
);
}
}
#[doc(alias = "jsc_context_throw")]
fn throw(&self, error_message: &str) {
unsafe {
ffi::jsc_context_throw(
self.as_ref().to_glib_none().0,
error_message.to_glib_none().0,
);
}
}
#[doc(alias = "jsc_context_throw_exception")]
fn throw_exception(&self, exception: &impl IsA<Exception>) {
unsafe {
ffi::jsc_context_throw_exception(
self.as_ref().to_glib_none().0,
exception.as_ref().to_glib_none().0,
);
}
}
#[doc(alias = "jsc_context_throw_with_name")]
fn throw_with_name(&self, error_name: &str, error_message: &str) {
unsafe {
ffi::jsc_context_throw_with_name(
self.as_ref().to_glib_none().0,
error_name.to_glib_none().0,
error_message.to_glib_none().0,
);
}
}
}
impl<O: IsA<Context>> ContextExt for O {}