Rust -> Python bindings
This guide explains how to add new Python bindings for Rust functions in the garaga_rs
crate.
Overview
The Python bindings are implemented using PyO3, which provides a safe and ergonomic way to create Python extensions in Rust. The bindings are located in the tools/garaga_rs/src/python_bindings
directory.
Adding a new binding
Create a new file in
tools/garaga_rs/src/python_bindings/
for your bindingAdd the module to
mod.rs
Implement your binding function
Register the function in the
garaga_rs
module
Type Conversions
Common Type Conversions
Python Int -> Rust BigUint
Rust BigUint -> Python Int
Python List -> Rust Vec
Python Bytes -> Rust Bytes
Field Elements
Error Handling
Converting Rust Errors to Python
Enum Conversion
Common Patterns
Function Declaration
Returning Results
Example Implementation
Here's a complete example showing common patterns:
Registering Your Function
Add your function to the garaga_rs
module in mod.rs
:
Using the Bindings
After implementing and registering your binding, you can use it in Python like this:
Testing
Add Python tests in
tests/hydra/
Test both successful and error cases
Test edge cases (empty lists, zero values)
Common Pitfalls
Always use
PyResult
for error handlingRemember to propagate errors with
?
Handle edge cases (e.g., zero values, maximum values)
Be careful with memory management for large data structures
Available Utilities
The following utilities are available in the codebase:
element_from_biguint
: Convert BigUint to Field Elementelement_to_biguint
: Convert Field Element to BigUintbiguint_to_u256
: Convert BigUint to u256
Building and Testing
Build/Update the Rust extension:
Run tests:
Best Practices
Keep bindings simple and focused
Use appropriate error handling
Test edge cases thoroughly
Follow existing patterns in the codebase
Last updated
Was this helpful?