From 7b1870a9ca7c309395eab6a6b3229476ea26def1 Mon Sep 17 00:00:00 2001 From: Andrew Sisley Date: Tue, 13 Feb 2024 12:05:24 -0500 Subject: [PATCH] Add filter test lens module --- .gitignore | 3 + tests/lenses/Makefile | 1 + tests/lenses/rust_wasm32_filter/Cargo.toml | 12 +++ tests/lenses/rust_wasm32_filter/src/lib.rs | 106 +++++++++++++++++++++ tests/lenses/utils.go | 10 ++ 5 files changed, 132 insertions(+) create mode 100644 tests/lenses/rust_wasm32_filter/Cargo.toml create mode 100644 tests/lenses/rust_wasm32_filter/src/lib.rs diff --git a/.gitignore b/.gitignore index 7bdb2237b4..40eac1780c 100644 --- a/.gitignore +++ b/.gitignore @@ -20,6 +20,9 @@ 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 +tests/lenses/rust_wasm32_filter/Cargo.lock +tests/lenses/rust_wasm32_filter/target +tests/lenses/rust_wasm32_filter/pkg # Ignore OS X metadata files. .history diff --git a/tests/lenses/Makefile b/tests/lenses/Makefile index 57807e10b2..5ebd3a0217 100644 --- a/tests/lenses/Makefile +++ b/tests/lenses/Makefile @@ -3,3 +3,4 @@ build: 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" + cargo build --target wasm32-unknown-unknown --manifest-path "./rust_wasm32_filter/Cargo.toml" diff --git a/tests/lenses/rust_wasm32_filter/Cargo.toml b/tests/lenses/rust_wasm32_filter/Cargo.toml new file mode 100644 index 0000000000..c3f815599f --- /dev/null +++ b/tests/lenses/rust_wasm32_filter/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "rust-wasm32-filter" +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" diff --git a/tests/lenses/rust_wasm32_filter/src/lib.rs b/tests/lenses/rust_wasm32_filter/src/lib.rs new file mode 100644 index 0000000000..5736d867f9 --- /dev/null +++ b/tests/lenses/rust_wasm32_filter/src/lib.rs @@ -0,0 +1,106 @@ +// 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, + PropertyNotFoundError{requested: String}, +} + +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."), + ModuleError::PropertyNotFoundError { requested } => + write!(f, "The requested property was not found. Requested: {}", requested), + } + } +} + +#[derive(Deserialize, Clone)] +pub struct Parameters { + pub src: String, + pub value: serde_json::Value, +} + +static PARAMETERS: RwLock> = RwLock::new(None); + +#[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> { + let parameter = lens_sdk::try_from_mem::(ptr)? + .ok_or(ModuleError::ParametersNotSetError)?; + + 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>, Box> { + let ptr = unsafe { next() }; + let mut input = match lens_sdk::try_from_mem::>(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 params = PARAMETERS.read()? + .clone() + .ok_or(ModuleError::ParametersNotSetError)? + .clone(); + + let value = input.get_mut(¶ms.src) + .ok_or(ModuleError::PropertyNotFoundError{requested: params.src.clone()})? + .clone(); + + if value != params.value { + return try_transform(); + } + + let result = input.clone(); + + let result_json = serde_json::to_vec(&result)?; + lens_sdk::free_transport_buffer(ptr)?; + Ok(Some(result_json)) +} diff --git a/tests/lenses/utils.go b/tests/lenses/utils.go index 97619a6124..0fab59d3a6 100644 --- a/tests/lenses/utils.go +++ b/tests/lenses/utils.go @@ -53,6 +53,16 @@ var PrependModulePath string = getPathRelativeToProjectRoot( "/tests/lenses/rust_wasm32_prepend/target/wasm32-unknown-unknown/debug/rust_wasm32_prepend.wasm", ) +// FilterModulePath is the path to the `Filter` lens module compiled to wasm. +// +// The module has two parameters: +// - `src` is a string and is the name of the property you wish to evaluate +// - `value` can be any valid json value and will be compared to the document value at the `src` location +// only documents with values that match this given value will be returned. +var FilterModulePath string = getPathRelativeToProjectRoot( + "/tests/lenses/rust_wasm32_filter/target/wasm32-unknown-unknown/debug/rust_wasm32_filter.wasm", +) + func getPathRelativeToProjectRoot(relativePath string) string { _, filename, _, _ := runtime.Caller(0) root := path.Dir(path.Dir(path.Dir(filename)))