Jute Parser & Rust Code Generator
A Rust implementation of the Apache ZooKeeper Jute IDL, providing a compiler-grade solution for protocol schema parsing and code generation.
This crate is designed for compiler-grade correctness, not just simple code generation, ensuring your generated code is based on a fully validated schema.
โจ Features
- ๐ Parsing: Full Jute grammar support, including
module,class, primitive types,vector<T>,map<K, V>, and cross-module type references. - ๐ Cross-File Resolution: Robust handling of relative file includes (
include "./path.jute";). - ๐ง Dependency Validation:
- Dependency graph resolution.
- Detects unknown types and ambiguous references.
- Detects circular dependencies.
- ๐ฆ Rust Code Generation:
- Idiomatic Rust output.
- Read/Write based serialization.
- No runtime reflection.
- ๐ Serialization & Deserialization: Provides high-performance, strongly-typed serialization logic.
- ๐งช Strong Test Coverage: Comprehensive tests for the parser, resolver, and serialization round-trips.
๐ Quick Start
1. Example Jute Schema
Create a schema file, e.g., schema/serialization.jute:
module serialization {
class Person {
int id;
string name;
boolean active;
}
class Company {
int id;
Person owner;
vector<Person> employees;
}
}
2. Generate Rust Code
Use the JuteGenerator to process your schema and generate source files:
use JuteGenerator;
new
.add_src_file // Input schema
.add_out_dir // Output directory src (curr crate) will be used as root
.generate
.unwrap;
3. Using Generated Code
The generated code is not automatically wired into your crate. You must include it manually:
// src/lib.rs or src/main.rs
4. ๐ Serialization & Deserialization
All generated types implement two core methods for I/O-based serialization:
;
;
Example Round-Trip:
use crate;
let person = Person ;
let mut buffer = Vecnew;
// Serialize
person.serialize.unwrap;
// Deserialize
let decoded = deserialize.unwrap;
assert_eq!;
// ... more assertions
A complete end-to-end example demonstrating how to use this crate is available here:View the full E2E example
๐ Include Semantics
Includes are resolved relative to the file that contains the include directive:
include "./common.jute";
include "../shared/types.jute";
The resolver ensures all paths are:
- Canonicalized
- Deduplicated
- Cycle-checked
โ Error Handling
All failures return a unified, descriptive error type:
use JuteError;
Errors are descriptive and contextual, including file paths and module names. They cover:
- Syntax errors in the schema
- Unknown or ambiguous types
- Circular dependencies
- IO failures
- Invalid schema definitions
๐ Project Structure
The project follows a classic compiler architecture:
src/
โโโ compiler/
โ โโโ ast_printer.rs // utility
โ โโโ ast.rs
โ โโโ dependency_resolver.rs
โ โโโ lexer.rs
โ โโโ parser.rs
โ โโโ state_machine.rs
โ โโโ token.rs
โ โโโ mod.rs
โโโ code_generator/
โ โโโ rust/
โ | โโโ utilities.rs
โ | โโโ writer.rs
โ | โโโ mod.rs
โ โโโ mod.rs
โโโ errors.rs
โโโ lib.rs
๐ฏ Design Goals
This crate prioritizes stability and correctness:
- Correctness > Convenience
- Explicit over implicit
- No hidden build steps
- Deterministic code generation
It is intended for:
- Zookepeer adapters
- Protocol tooling
- Schema-driven serialization
๐ง Inspiration
- Apache ZooKeeper Jute
- Protocol Buffers (IDL-style)
Missing Implementation
Following features are currently not supported
- Containerized recursive schema
- Can be enhanced with async versions of serialization.
๐ License
This project is licensed under the MIT License.
๐ค Contributing
Contributions are welcome! Focus areas include:
- Adding new Jute features
- Improving error diagnostics
- Extending code generators (e.g., for other languages)
- Improving test coverage
- Implementing missing features
- benchmarking