Rod

Architecture

Understanding the Zero-Copy Design and Bridge Tax.

Architecture

Rod is built on a philosophy of abstracted access. Instead of forcing you to serialize data into JSON strings to pass them between languages, Rod reads the host language's memory directly through an abstraction layer.

The RodInput Trait

The core validation engine uses the RodInput trait to interact with data. This trait allows the same Rust code to validate different memory layouts.

Implementation: JsonInput

Wraps a serde_json::Value. Validation happens directly on the JSON tree in Rust memory.

// Logic inside core/src/io/json.rs
impl<'a> RodInput<'a> for JsonInput<'a> {
    fn get_type(&self) -> DataType { ... }
    fn as_str(&self) -> Option<Cow<'a, str>> { ... }
}

Implementation: JsInput

Wraps a JsValue. Rod uses Reflect.get() to read properties from the JavaScript heap on-demand.

// Logic inside bindings/rod-wasm/src/lazy.rs
impl<'a> RodInput<'a> for JsInput {
    fn with_key(&self, key: &str, ...) {
        let val = js_sys::Reflect::get(&self.value, &key_js);
        // ...
    }
}

Implementation: PyInput

Wraps a PyObject. Rod uses the Python C-API to read dictionaries and lists directly.

// Logic inside bindings/rod-pyo3/src/py_input.rs
impl<'a> RodInput<'a> for PyInput<'a> {
    fn keys(&self) -> Option<Box<dyn Iterator<Item = Cow<'a, str>>>> {
        let dict = self.0.downcast::<PyDict>().ok()?;
        let keys = dict.keys();
        // ...
    }
}

The "Bridge Tax"

When Rod runs in JavaScript or Python, it must "cross the bridge" to communicate with the Rust core. This round-trip has a fixed cost of approximately 1,500ns – 4,000ns.

  • For small objects, this tax dominates the execution time, making Rod slower than native JS/Python libraries.
  • For massive datasets, the bridge tax is paid only once (via Batch APIs), allowing Rod's high-performance Rust core to win.

On this page