Skip to content

Commit 0f4d54b

Browse files
authored
Merge pull request #48 from Shopify/ap.provider-for-rust-target
Use provider for rust target
2 parents d7432e0 + 6dd904c commit 0f4d54b

File tree

10 files changed

+513
-242
lines changed

10 files changed

+513
-242
lines changed

.github/workflows/ci.yml

+7-3
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,16 @@ jobs:
2727
run: cargo fmt --check
2828
- name: Run clippy
2929
run: cargo clippy --all-features -- -D warnings
30+
- name: Run clippy (wasm32-wasip1 target)
31+
run: cargo clippy --target wasm32-wasip1 --all-features --workspace --exclude shopify_function_wasm_api_trampoline --exclude integration_tests -- -D warnings
3032
- name: Run clippy (tests)
3133
run: cargo clippy --tests --all-features
3234
- name: Run clippy (benches)
3335
run: cargo clippy --benches --all-features
3436
- name: Run clippy (examples)
3537
run: cargo clippy --examples --all-features
38+
- name: Run clippy (examples, wasm32-wasip1 target)
39+
run: cargo clippy --examples --target wasm32-wasip1 --all-features
3640

3741
test:
3842
runs-on: shopify-ubuntu-latest
@@ -55,9 +59,9 @@ jobs:
5559
cargo-target-${{ hashFiles('Cargo.toml') }}
5660
cargo-target
5761
- name: Run tests
58-
# we exclude the api crate because it cannot be tested in isolation
59-
# due to needing the trampoline wasm to be merged into it
60-
run: cargo test --workspace --exclude shopify_function_wasm_api
62+
run: cargo test
63+
- name: Run tests (examples)
64+
run: cargo test --examples
6165

6266
build:
6367
runs-on: shopify-ubuntu-latest

api/Cargo.toml

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ edition = "2021"
77
shopify_function_wasm_api_core = { path = "../core", version = "0.0.1" }
88
thiserror = "2.0"
99

10+
[target.'cfg(not(target_family = "wasm"))'.dependencies]
11+
shopify_function_wasm_api_provider = { path = "../provider", version = "0.0.1" }
12+
serde_json = "1.0"
13+
rmp-serde = "1.3"
14+
1015
[[example]]
1116
name = "echo"
1217
path = "examples/echo.rs"

api/examples/echo.rs

+23
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ fn echo(value: Value) -> Value {
2020
value
2121
}
2222

23+
#[derive(Debug, PartialEq)]
2324
enum Value {
2425
Null,
2526
Bool(bool),
@@ -113,3 +114,25 @@ impl Serialize for Value {
113114
}
114115
}
115116
}
117+
118+
#[cfg(test)]
119+
mod tests {
120+
use super::*;
121+
122+
#[test]
123+
fn test_echo() {
124+
let input = serde_json::json!({});
125+
let context = Context::new_with_input(input);
126+
let api_value = context.input_get().unwrap();
127+
let input: Value = Deserialize::deserialize(&api_value).unwrap();
128+
let result = echo(input);
129+
130+
assert_eq!(
131+
result,
132+
Value::Object {
133+
foo_value: Box::new(Value::Null),
134+
bar_value: Box::new(Value::Null),
135+
}
136+
);
137+
}
138+
}

api/src/lib.rs

+164-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ pub mod write;
1111
pub use read::Deserialize;
1212
pub use write::Serialize;
1313

14+
#[cfg(target_family = "wasm")]
1415
#[link(wasm_import_module = "shopify_function_v0.0.1")]
1516
extern "C" {
1617
// Common API.
@@ -62,6 +63,149 @@ extern "C" {
6263
fn shopify_function_intern_utf8_str(context: ContextPtr, ptr: *const u8, len: usize) -> usize;
6364
}
6465

66+
#[cfg(not(target_family = "wasm"))]
67+
mod provider_fallback {
68+
use super::{ContextPtr, Val, WriteResult};
69+
70+
// Read API.
71+
pub(crate) unsafe fn shopify_function_input_get(context: ContextPtr) -> Val {
72+
shopify_function_wasm_api_provider::read::shopify_function_input_get(context)
73+
}
74+
pub(crate) unsafe fn shopify_function_input_get_val_len(
75+
context: ContextPtr,
76+
scope: Val,
77+
) -> usize {
78+
shopify_function_wasm_api_provider::read::shopify_function_input_get_val_len(context, scope)
79+
}
80+
pub(crate) unsafe fn shopify_function_input_read_utf8_str(
81+
context: ContextPtr,
82+
src: usize,
83+
out: *mut u8,
84+
len: usize,
85+
) {
86+
let src =
87+
shopify_function_wasm_api_provider::read::shopify_function_input_get_utf8_str_addr(
88+
context, src,
89+
);
90+
std::ptr::copy(src as _, out, len);
91+
}
92+
pub(crate) unsafe fn shopify_function_input_get_obj_prop(
93+
context: ContextPtr,
94+
scope: Val,
95+
ptr: *const u8,
96+
len: usize,
97+
) -> Val {
98+
shopify_function_wasm_api_provider::read::shopify_function_input_get_obj_prop(
99+
context, scope, ptr as _, len,
100+
)
101+
}
102+
pub(crate) unsafe fn shopify_function_input_get_interned_obj_prop(
103+
context: ContextPtr,
104+
scope: Val,
105+
interned_string_id: shopify_function_wasm_api_core::InternedStringId,
106+
) -> Val {
107+
shopify_function_wasm_api_provider::read::shopify_function_input_get_interned_obj_prop(
108+
context,
109+
scope,
110+
interned_string_id,
111+
)
112+
}
113+
pub(crate) unsafe fn shopify_function_input_get_at_index(
114+
context: ContextPtr,
115+
scope: Val,
116+
index: usize,
117+
) -> Val {
118+
shopify_function_wasm_api_provider::read::shopify_function_input_get_at_index(
119+
context, scope, index,
120+
)
121+
}
122+
123+
// Write API.
124+
pub(crate) unsafe fn shopify_function_output_new_bool(
125+
context: ContextPtr,
126+
bool: u32,
127+
) -> WriteResult {
128+
shopify_function_wasm_api_provider::write::shopify_function_output_new_bool(context, bool)
129+
}
130+
pub(crate) unsafe fn shopify_function_output_new_null(context: ContextPtr) -> WriteResult {
131+
shopify_function_wasm_api_provider::write::shopify_function_output_new_null(context)
132+
}
133+
pub(crate) unsafe fn shopify_function_output_finalize(context: ContextPtr) -> WriteResult {
134+
shopify_function_wasm_api_provider::write::shopify_function_output_finalize(context)
135+
}
136+
pub(crate) unsafe fn shopify_function_output_new_i32(
137+
context: ContextPtr,
138+
int: i32,
139+
) -> WriteResult {
140+
shopify_function_wasm_api_provider::write::shopify_function_output_new_i32(context, int)
141+
}
142+
pub(crate) unsafe fn shopify_function_output_new_f64(
143+
context: ContextPtr,
144+
float: f64,
145+
) -> WriteResult {
146+
shopify_function_wasm_api_provider::write::shopify_function_output_new_f64(context, float)
147+
}
148+
pub(crate) unsafe fn shopify_function_output_new_utf8_str(
149+
context: ContextPtr,
150+
ptr: *const u8,
151+
len: usize,
152+
) -> WriteResult {
153+
let result =
154+
shopify_function_wasm_api_provider::write::shopify_function_output_new_utf8_str(
155+
context, len,
156+
);
157+
let write_result =
158+
WriteResult::from_repr((result >> 32) as u32).expect("Invalid write result");
159+
let dst = result as u32;
160+
if write_result == WriteResult::Ok {
161+
std::ptr::copy(ptr as _, dst as _, len);
162+
}
163+
write_result
164+
}
165+
pub(crate) unsafe fn shopify_function_output_new_interned_utf8_str(
166+
context: ContextPtr,
167+
id: shopify_function_wasm_api_core::InternedStringId,
168+
) -> WriteResult {
169+
shopify_function_wasm_api_provider::write::shopify_function_output_new_interned_utf8_str(
170+
context, id,
171+
)
172+
}
173+
pub(crate) unsafe fn shopify_function_output_new_object(
174+
context: ContextPtr,
175+
len: usize,
176+
) -> WriteResult {
177+
shopify_function_wasm_api_provider::write::shopify_function_output_new_object(context, len)
178+
}
179+
pub(crate) unsafe fn shopify_function_output_finish_object(context: ContextPtr) -> WriteResult {
180+
shopify_function_wasm_api_provider::write::shopify_function_output_finish_object(context)
181+
}
182+
pub(crate) unsafe fn shopify_function_output_new_array(
183+
context: ContextPtr,
184+
len: usize,
185+
) -> WriteResult {
186+
shopify_function_wasm_api_provider::write::shopify_function_output_new_array(context, len)
187+
}
188+
pub(crate) unsafe fn shopify_function_output_finish_array(context: ContextPtr) -> WriteResult {
189+
shopify_function_wasm_api_provider::write::shopify_function_output_finish_array(context)
190+
}
191+
192+
// Other.
193+
pub(crate) unsafe fn shopify_function_intern_utf8_str(
194+
context: ContextPtr,
195+
ptr: *const u8,
196+
len: usize,
197+
) -> usize {
198+
let result =
199+
shopify_function_wasm_api_provider::shopify_function_intern_utf8_str(context, len);
200+
let id = (result >> usize::BITS) as usize;
201+
let dst = result as usize;
202+
std::ptr::copy(ptr as _, dst as _, len);
203+
id
204+
}
205+
}
206+
#[cfg(not(target_family = "wasm"))]
207+
use provider_fallback::*;
208+
65209
#[derive(Clone, Copy)]
66210
pub struct InternedStringId(shopify_function_wasm_api_core::InternedStringId);
67211

@@ -110,12 +254,12 @@ impl Value {
110254
pub fn as_string(&self) -> Option<String> {
111255
match self.nan_box.try_decode() {
112256
Ok(ValueRef::String { ptr, len }) => {
113-
let len = if len as u64 == NanBox::MAX_VALUE_LENGTH {
257+
let len = if len == NanBox::MAX_VALUE_LENGTH {
114258
unsafe {
115259
shopify_function_input_get_val_len(
116260
self.context.as_ptr() as _,
117261
self.nan_box.to_bits(),
118-
) as usize
262+
)
119263
}
120264
} else {
121265
len
@@ -191,12 +335,12 @@ impl Value {
191335
pub fn array_len(&self) -> Option<usize> {
192336
match self.nan_box.try_decode() {
193337
Ok(ValueRef::Array { len, .. }) => {
194-
let len = if len as u64 == NanBox::MAX_VALUE_LENGTH {
338+
let len = if len == NanBox::MAX_VALUE_LENGTH {
195339
unsafe {
196340
shopify_function_input_get_val_len(
197341
self.context.as_ptr() as _,
198342
self.nan_box.to_bits(),
199-
) as usize
343+
)
200344
}
201345
} else {
202346
len
@@ -255,10 +399,26 @@ impl std::fmt::Display for ContextError {
255399
}
256400

257401
impl Context {
402+
#[cfg(target_family = "wasm")]
258403
pub fn new() -> Self {
259404
Self(unsafe { shopify_function_context_new() })
260405
}
261406

407+
#[cfg(not(target_family = "wasm"))]
408+
pub fn new() -> Self {
409+
panic!("Cannot run in non-WASM environment; use `new_with_input` instead")
410+
}
411+
412+
#[cfg(not(target_family = "wasm"))]
413+
pub fn new_with_input(input: serde_json::Value) -> Self {
414+
let bytes = rmp_serde::to_vec(&input).unwrap();
415+
Self(
416+
shopify_function_wasm_api_provider::shopify_function_context_new_from_msgpack_bytes(
417+
bytes,
418+
),
419+
)
420+
}
421+
262422
pub fn input_get(&self) -> Result<Value, ContextError> {
263423
let val = unsafe { shopify_function_input_get(self.0) };
264424
NonNull::new(self.0 as _)

0 commit comments

Comments
 (0)