Skip to content

Create flagd-evaluator WebAssembly library for JSON Logic evaluation - #1

Merged
aepfli merged 4 commits into
mainfrom
copilot/create-flagd-evaluator-library
Dec 1, 2025
Merged

aepfli merged 4 commits into
mainfrom
copilot/create-flagd-evaluator-library

Conversation

Copilot AI commented Dec 1, 2025 •

Copy link
Copy Markdown
Contributor
  • Create project structure and Cargo.toml
  • Implement memory management (src/memory.rs)
  • Implement error handling (src/error.rs)
  • Implement custom operators (src/operators/mod.rs, src/operators/custom.rs)
  • Implement main library (src/lib.rs)
  • Add integration tests (tests/integration_tests.rs)
  • Add Java example (examples/java/FlagdEvaluatorExample.java)
  • Create GitHub Actions CI workflow (.github/workflows/ci.yml)
  • Create GitHub Actions Release workflow (.github/workflows/release.yml)
  • Create comprehensive README.md
  • Create CONTRIBUTING.md
  • Create LICENSE file (Apache-2.0)
  • Create .gitignore
  • Verify build and tests pass
  • Run code review
  • Fix CI: use dtolnay/rust-toolchain instead of dtolnay/rust-action
  • Update release workflow with proper wasm-opt optimization

WASM Size

The WASM module is ~1.4MB unoptimized and ~1.3MB after wasm-opt optimization. The size is due to the full datalogic-rs JSON Logic implementation which includes:

  • 50+ JSON Logic operators
  • regex crate for pattern matching
  • chrono crate for date/time operations

To reduce size further, options include:

  1. Using a lighter JSON Logic library (fewer operators)
  2. Implementing only the needed operators from scratch
Original prompt

Project Creation Prompt for flagd-evaluator

Create a complete Rust WebAssembly library called flagd-evaluator that provides JSON Logic evaluation with custom operators, specifically designed to work with Chicory (pure Java WebAssembly runtime).

Project Structure

flagd-evaluator/
├── .github/
│   └── workflows/
│       ├── ci.yml
│       └── release.yml
├── src/
│   ├── lib.rs
│   ├── operators/
│   │   ├── mod.rs
│   │   └── custom.rs
│   ├── memory.rs
│   └── error.rs
├── examples/
│   └── java/
│       └── FlagdEvaluatorExample.java
├── tests/
│   └── integration_tests.rs
├── Cargo.toml
├── README.md
├── CONTRIBUTING.md
├── LICENSE
└── .gitignore

Core Requirements

1. Cargo.toml Configuration

[package]
name = "flagd-evaluator"
version = "0.1.0"
edition = "2021"
authors = ["Your Name <your.email@example.com>"]
description = "A WebAssembly-based JSON Logic evaluator with custom operators for feature flag evaluation"
license = "Apache-2.0"
repository = "https://github.com/yourusername/flagd-evaluator"
readme = "README.md"
keywords = ["jsonlogic", "wasm", "feature-flags", "evaluator", "chicory"]
categories = ["wasm", "web-programming"]

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

[dependencies]
datalogic-rs = "4.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

[dev-dependencies]
wasm-bindgen-test = "0.3"

[profile.release]
opt-level = "z"
lto = true
codegen-units = 1
strip = true
panic = "abort"

2. Main Library Implementation (src/lib.rs)

Requirements:

  • Export a single main function: evaluate_logic
  • Accept: rule JSON string, data JSON string (both as packed pointers: ptr + length)
  • Return: packed pointer to result JSON string (always JSON, includes error field if failed)
  • Memory management: allocate and return pointer that caller must free
  • Export allocator functions: alloc, dealloc for memory management

Function Signature:

#[no_mangle]
pub extern "C" fn evaluate_logic(
    rule_ptr: *const u8,
    rule_len: u32,
    data_ptr: *const u8,
    data_len: u32,
) -> u64; // Returns packed pointer (upper 32 bits = ptr, lower 32 bits = length)

Response Format (Always JSON):

// Success case
{
  "success": true,
  "result": <actual_result>,
  "error": null
}

// Error case
{
  "success": false,
  "result": null,
  "error": "error message here"
}

3. Custom Operator Implementation (src/operators/custom.rs)

Implement one custom operator called "fractional" that performs fractional evaluation (consistent hashing for A/B testing):

// Operator: "fractional"
// Input: [{ "var": "targetingKey" }, [bucketBy, percentage1, percentage2, ...]]
// Example: {"fractional": [{"var": "user.id"}, ["bucket1", 50, "bucket2", 50]]}
// Returns: one of the bucket names based on consistent hashing

Use murmurhash3 or a simple hash function for consistent distribution.

4. Memory Management (src/memory.rs)

Implement:

  • alloc(len: u32) -> *mut u8 - Allocate memory from WASM linear memory
  • dealloc(ptr: *mut u8, len: u32) - Free allocated memory
  • Helper functions for packing/unpacking pointers with length

5. Error Handling (src/error.rs)

Create a proper error type that serializes to JSON:

pub struct EvaluatorError {
    pub message: String,
    pub error_type: ErrorType,
}

pub enum ErrorType {
    ParseError,
    EvaluationError,
    MemoryError,
    InvalidInput,
}

6. README.md

Must include:

  • Project overview and purpose
  • Key features (custom operators, Chicory compatibility, zero JNI)
  • Installation instructions
  • Usage examples (both Rust and Java with Chicory)
  • Building instructions for wasm32-unknown-unknown
  • API documentation (exported functions, memory model)
  • Custom operator documentation
  • Contributing guidelines
  • License information

7. GitHub Actions CI/CD (.github/workflows/ci.yml)

CI Pipeline:

  • Trigger: on push and pull request to main
  • Jobs:
    • test: Run cargo test on ubuntu-latest
    • clippy: Run cargo clippy -- -D warnings
    • fmt: Run cargo fmt -- --check
    • build-wasm:
      • Install wasm32-unknown-unknown target
      • Build with cargo build --target wasm32-unknown-unknown --release
      • Upload artifact: flagd_evaluator.wasm
    • validate-size: Check that .wasm file is under 500KB

8. GitHub Actions Release (.github/workflows/release.yml)

Release Pipeline:

  • Trigger: on git tag push (v*..)
  • Jobs:
    • Build WASM for release
    • Optimize with wasm-opt (if available)
    • Create GitHub release
    • Attach flagd_evaluator.wasm as release asset
    • Generate checksums (SHA256)

9. Integration Tests (tests/integration_tests.rs)

Include tests for:

  • Basic JSON Logic operations
  • Custom fractional operator
  • Error handling (invalid JSON, invalid logic)
  • Memory safety
  • Edge cases (empty strings, null values, nested operations)

10. Java Example (examples/java/FlagdEvaluatorExample.java)

Provide...


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

…tom operators

Co-authored-by: aepfli <9987394+aepfli@users.noreply.github.com>
Copilot AI changed the title [WIP] Create complete Rust WebAssembly library flagd-evaluator Create flagd-evaluator WebAssembly library for JSON Logic evaluation Dec 1, 2025
Copilot AI requested a review from aepfli December 1, 2025 20:49
@aepfli

aepfli commented Dec 1, 2025

Copy link
Copy Markdown
Contributor

@copilot Can we reduce the wasm module size, and I

@aepfli
aepfli marked this pull request as ready for review December 1, 2025 20:56
Copilot AI and others added 2 commits December 1, 2025 21:02
Co-authored-by: aepfli <9987394+aepfli@users.noreply.github.com>
Co-authored-by: aepfli <9987394+aepfli@users.noreply.github.com>
@aepfli
aepfli merged commit 4d11f03 into main Dec 1, 2025

Copilot AI commented Dec 1, 2025

Copy link
Copy Markdown
Contributor Author

@copilot Can we reduce the wasm module size, and I

The CI build failures are now fixed (c1cd6dd) - the issue was using dtolnay/rust-action instead of dtolnay/rust-toolchain.

Regarding WASM size reduction:

  • Current: ~1.4MB → ~1.3MB after wasm-opt optimization
  • Main contributor: datalogic-rs pulls in regex (~400KB) and chrono (~200KB) for full JSON Logic support (50+ operators)

Options to reduce further:

  1. Switch to a lighter JSON Logic library like jsonlogic (only depends on serde_json)
  2. Implement only the needed operators from scratch

The release workflow now properly uses wasm-opt with --enable-bulk-memory --enable-nontrapping-float-to-int flags.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants