Skip to content

Commit

Permalink
Add prepend test lens module
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewSisley committed Feb 13, 2024
1 parent e99a809 commit 1756464
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ tests/lenses/rust_wasm32_remove/pkg
tests/lenses/rust_wasm32_copy/Cargo.lock
tests/lenses/rust_wasm32_copy/target
tests/lenses/rust_wasm32_copy/pkg
tests/lenses/rust_wasm32_prepend/Cargo.lock
tests/lenses/rust_wasm32_prepend/target
tests/lenses/rust_wasm32_prepend/pkg

# Ignore OS X metadata files.
.history
Expand Down
1 change: 1 addition & 0 deletions tests/lenses/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ build:
cargo build --target wasm32-unknown-unknown --manifest-path "./rust_wasm32_set_default/Cargo.toml"
cargo build --target wasm32-unknown-unknown --manifest-path "./rust_wasm32_remove/Cargo.toml"
cargo build --target wasm32-unknown-unknown --manifest-path "./rust_wasm32_copy/Cargo.toml"
cargo build --target wasm32-unknown-unknown --manifest-path "./rust_wasm32_prepend/Cargo.toml"
12 changes: 12 additions & 0 deletions tests/lenses/rust_wasm32_prepend/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[package]
name = "rust-wasm32-prepend"
version = "0.1.0"
edition = "2018"

[lib]
crate-type = ["cdylib"]

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.87"
lens_sdk = "^0.5"
111 changes: 111 additions & 0 deletions tests/lenses/rust_wasm32_prepend/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use std::collections::HashMap;
use std::sync::RwLock;
use std::error::Error;
use std::{fmt, error};
use serde::Deserialize;
use lens_sdk::StreamOption;
use lens_sdk::option::StreamOption::{Some, None, EndOfStream};

#[link(wasm_import_module = "lens")]
extern "C" {
fn next() -> *mut u8;
}

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
enum ModuleError {
ParametersNotSetError,
}

impl error::Error for ModuleError { }

impl fmt::Display for ModuleError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &*self {
ModuleError::ParametersNotSetError => f.write_str("Parameters have not been set."),
}
}
}

#[derive(Deserialize, Clone)]
pub struct Parameters {
pub values: Vec<HashMap<String, String>>,
}

static PARAMETERS: RwLock<StreamOption<Parameters>> = RwLock::new(None);
static PARAM_INDEX: RwLock<usize> = RwLock::new(0);

#[no_mangle]
pub extern fn alloc(size: usize) -> *mut u8 {
lens_sdk::alloc(size)
}

#[no_mangle]
pub extern fn set_param(ptr: *mut u8) -> *mut u8 {
match try_set_param(ptr) {
Ok(_) => lens_sdk::nil_ptr(),
Err(e) => lens_sdk::to_mem(lens_sdk::ERROR_TYPE_ID, &e.to_string().as_bytes())
}
}

fn try_set_param(ptr: *mut u8) -> Result<(), Box<dyn Error>> {
let parameter = lens_sdk::try_from_mem::<Parameters>(ptr)?
.ok_or(ModuleError::ParametersNotSetError)?
.clone();

let mut dst = PARAMETERS.write()?;
*dst = Some(parameter);
Ok(())
}

#[no_mangle]
pub extern fn transform() -> *mut u8 {
match try_transform() {
Ok(o) => match o {
Some(result_json) => lens_sdk::to_mem(lens_sdk::JSON_TYPE_ID, &result_json),
None => lens_sdk::nil_ptr(),
EndOfStream => lens_sdk::to_mem(lens_sdk::EOS_TYPE_ID, &[]),
},
Err(e) => lens_sdk::to_mem(lens_sdk::ERROR_TYPE_ID, &e.to_string().as_bytes())
}
}

fn try_transform() -> Result<StreamOption<Vec<u8>>, Box<dyn Error>> {
let params = PARAMETERS.read()?
.clone()
.ok_or(ModuleError::ParametersNotSetError)?
.clone();

let param_index = PARAM_INDEX.read()?
.clone();

if param_index < params.values.len() {
let result = &params.values[param_index];
let result_json = serde_json::to_vec(&result)?;

let mut dst = PARAM_INDEX.write()?;
*dst = param_index+1;
return Ok(Some(result_json))
}

// Note: The following is a very unperformant, but simple way of yielding the input documents,
// as this module is only used for testing, this is preferred.

let ptr = unsafe { next() };
let input = match lens_sdk::try_from_mem::<HashMap<String, serde_json::Value>>(ptr)? {
Some(v) => v,
// Implementations of `transform` are free to handle nil however they like. In this
// implementation we chose to return nil given a nil input.
None => return Ok(None),
EndOfStream => return Ok(EndOfStream)
};

let result = input.clone();

let result_json = serde_json::to_vec(&result)?;
lens_sdk::free_transport_buffer(ptr)?;
Ok(Some(result_json))
}
9 changes: 9 additions & 0 deletions tests/lenses/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ var CopyModulePath string = getPathRelativeToProjectRoot(
"/tests/lenses/rust_wasm32_copy/target/wasm32-unknown-unknown/debug/rust_wasm32_copy.wasm",
)

// PrependModulePath is the path to the `Prepend` lens module compiled to wasm.
//
// The module has one parameter:
// - `values` is an array of `map[string]string`s, the module will yield these documents before
// any documents fed to it (from Defra).
var PrependModulePath string = getPathRelativeToProjectRoot(
"/tests/lenses/rust_wasm32_prepend/target/wasm32-unknown-unknown/debug/rust_wasm32_prepend.wasm",
)

func getPathRelativeToProjectRoot(relativePath string) string {
_, filename, _, _ := runtime.Caller(0)
root := path.Dir(path.Dir(path.Dir(filename)))
Expand Down

0 comments on commit 1756464

Please sign in to comment.