1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! JavaScriptCore Bindings
//!
//! Evaluate JavaScript programs from within an app, and support
//! JavaScript scripting of your app.

#![warn(missing_docs)]
#![deny(
    trivial_numeric_casts,
    unstable_features,
    unused_import_braces,
    unused_qualifications
)]

extern crate javascriptcore_sys as sys;

mod base;
mod class;
mod context;
mod contextgroup;
mod exception;
mod object;
mod string;
mod value;

pub use crate::base::{check_script_syntax, evaluate_script, garbage_collect};
pub use crate::sys::{JSType, JSTypedArrayType};

/// A JavaScript class.
///
/// Used with `JSObjectMake` to construct objects with custom
/// behavior.
///
/// TODO: Fix `JSObjectMake` reference once it has been wrapped.
pub struct JSClass {
    raw: sys::JSClassRef,
}

/// A JavaScript execution context.
///
/// Holds the global object and other execution state.
pub struct JSContext {
    raw: sys::JSGlobalContextRef,
}

/// A group that associates JavaScript contexts with one another.
///
/// Contexts in the same group may share and exchange JavaScript
/// objects. Sharing and/or exchanging JavaScript objects between
/// contexts in different groups will produce undefined behavior.
/// When objects from the same context group are used in multiple
/// threads, explicit synchronization is required.
pub struct JSContextGroup {
    raw: sys::JSContextGroupRef,
}

/// A wrapper for a [`JSValue`] that contains an exception.
///
/// [`JSValue`]: struct.JSValue.html
#[derive(Debug)]
pub struct JSException {
    value: JSValue,
}

/// A JavaScript object.
///
/// An `JSObject` is a [`JSValue`]. This is implemented by having
/// `JSObject` implement the `Deref` trait so that anything that
/// expects a `JSValue` can receive a `JSObject` as well.
///
/// [`JSValue`]: struct.JSValue.html
pub struct JSObject {
    raw: sys::JSObjectRef,
    value: JSValue,
}

/// A UTF16 character buffer.
///
/// The fundamental string representation in JavaScript. Since
/// this is using a UTF16 encoding and Rust strings are using
/// UTF8 encoding, converting between string representations
/// is not cheap.
///
/// In this crate, implementations of the conversion traits
/// `Into` and `From` are provided for `JSString`. This allows
/// conversion from `&str` and `String` into `JSString`:
///
/// ```
/// # use javascriptcore::JSString;
/// let j: JSString = "abc".into();
/// ```
///
/// Similarly, a `JSString` can be converted to a `String`
/// via a conversion trait or directly:
///
/// ```
/// # use javascriptcore::JSString;
/// let j: JSString = "abc".into();
/// let s: String = (&j).into(); // Requires a reference.
/// let s: String = j.to_string();
/// ```
///
/// In this crate, functions that need a `JSString` use
/// generics so that they can take anything that can be
/// converted to a `JSString` instead. This allows the
/// caller to pass an `&str` or `String`, or to cache a
/// previously converted `JSString` and pass that directly.
///
/// A `JSString` is not a [`JSValue`] and so it can not be
/// passed where a `JSValue` is expected. Instead, it must
/// be boxed using [`JSValue::new_string`].
///
/// [`JSValue`]: struct.JSValue.html
/// [`JSValue::new_string`]: struct.JSValue.html#method.new_string
#[derive(Eq)]
pub struct JSString {
    raw: sys::JSStringRef,
}

/// A JavaScript value.
///
/// The base type for all JavaScript values, and polymorphic functions
/// on them.
///
/// All values passed between Rust and JavaScriptCore will be boxed with
/// a `JSValue`.
///
/// # Creating JS values
///
/// * [`JSValue::new_undefined`]
/// * [`JSValue::new_null`]
/// * [`JSValue::new_boolean`]
/// * [`JSValue::new_number`]
/// * [`JSValue::new_string`]
/// * [`JSValue::new_from_json`]
///
/// # JSON
///
/// * [`JSValue::new_from_json`]
/// * [`JSValue::to_json_string`]
///
/// # Retrieving Rust values
///
/// * [`JSValue::as_boolean`]
/// * [`JSValue::as_number`]
/// * [`JSValue::as_object`]
/// * [`JSValue::as_string`]
///
/// [`JSValue::new_undefined`]: #method.new_undefined
/// [`JSValue::new_null`]: #method.new_null
/// [`JSValue::new_boolean`]: #method.new_boolean
/// [`JSValue::new_number`]: #method.new_number
/// [`JSValue::new_string`]: #method.new_string
/// [`JSValue::new_from_json`]: #method.new_from_json
/// [`JSValue::to_json_string`]: #method.to_json_string
/// [`JSValue::as_boolean`]: #method.as_boolean
/// [`JSValue::as_number`]: #method.as_number
/// [`JSValue::as_object`]: #method.as_object
/// [`JSValue::as_string`]: #method.as_string
#[derive(Debug)]
pub struct JSValue {
    raw: sys::JSValueRef,
    ctx: sys::JSContextRef,
}