# browser-protocol
[](https://crates.io/crates/browser-protocol)
[](https://docs.rs/browser-protocol)
[](https://opensource.org/licenses/MIT)
A high-performance, zero-allocation, fully compile-safe Rust representation of the **Chrome DevTools Protocol (CDP)**, generated directly from the official protocol definitions.
---
## 🚀 Key Design Goals & Features
Most auto-generated CDP crates output raw, unidiomatic APIs with substantial runtime allocation overhead. This library is designed from the ground up to solve these issues:
### 1. Idiomatic Rust Naming Conventions
* All generated struct fields, getters, and builder setter methods are translated from the protocol's raw `camelCase` to standard Rust `snake_case` (e.g., `transitionType` becomes `transition_type`, and `backendDOMNodeId` becomes `backend_dom_node_id`).
* Standard `#[serde(rename = "...")]` attributes ensure the serialized JSON wire protocol matches the exact formats required by Chrome.
### 2. Zero-Copy String Management
* Utilizes `Cow<'a, str>` instead of allocating heap memory (`String`) for string properties.
* String arguments in builders use `impl Into<Cow<'a, str>>`, allowing you to pass static string literals (`&str`) or owned strings without unnecessary heap allocations.
### 3. Compile-Time Argument Safety
* The builder pattern differentiates between **required** and **optional** parameters. Required parameters are passed directly as arguments to the `builder(...)` function, guaranteeing protocol compliance at compile time:
```rust
let nav = NavigateParams::builder("https://www.rust-lang.org")
.transition_type(TransitionType::Typed)
.build();
```
### 4. Zero Dependencies & No Async Runtime Lock-in
* Contains **zero bloated dependencies** (depends only on `serde` and `serde_json`).
* Does not include a WebSocket client or force a specific async runtime (like `tokio`). This keeps the package extremely lightweight, compile-fast, and compatible with any async runtime or network stack.
---
## 📦 Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
browser-protocol = { version = "0.1.3", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
```
---
## 🛠 Usage Examples
### 1. Constructing a Request with Optional Parameters
```rust
use browser_protocol::page::{NavigateParams, TransitionType};
fn main() {
// 1. Build the command parameters
let nav = NavigateParams::builder("https://www.rust-lang.org")
.transition_type(TransitionType::Typed)
.build();
// 2. Read-only getters
println!("Navigating to: {}", nav.url()); // prints "https://www.rust-lang.org"
// 3. Serialize to wire protocol payload (skips unset Option fields)
let payload = serde_json::to_string(&nav).unwrap();
println!("Payload: {}", payload);
// Output: {"url":"https://www.rust-lang.org","transitionType":"typed"}
}
```
### 2. Handling Command Request/Response Types
Every parameter struct implements `crate::CdpCommand<'a>` which binds it to its command method and its corresponding response (`Returns`) type:
```rust
use browser_protocol::accessibility::{GetPartialAXTreeParams, GetPartialAXTreeReturns};
use browser_protocol::dom::NodeId;
use browser_protocol::CdpCommand;
fn get_accessibility_tree() {
let params = GetPartialAXTreeParams::builder()
.node_id(NodeId::from(42))
.fetch_relatives(true)
.build();
// The trait binds this command to its method name and response type:
assert_eq!(GetPartialAXTreeParams::METHOD, "Accessibility.getPartialAXTree");
// In your network client:
// let response_json = websocket.send_command(GetPartialAXTreeParams::METHOD, ¶ms).await;
// let response: GetPartialAXTreeReturns = serde_json::from_str(&response_json).unwrap();
}
```
---
## 🏗 Code Generation Mechanics
The code is dynamically compiled using a custom Python script that performs advanced schema analysis:
1. **Fixed-Point Lifetime Propagation Pass**: The generator performs iterative analysis over the CDP types to detect circular type references, nesting, and dependency hierarchies. It automatically determines which types must have a lifetime parameter (`<'a>`) and wraps recursive structures inside `Box` to prevent infinite-size compilation errors.
2. **HTML/Markdown Escaping**: Schema documentation from the Chrome DevTools Protocol contains raw markdown and HTML brackets. The generator cleans and escapes these brackets into valid Rustdoc format, keeping compilation entirely warning-free.
3. **Domain-Specific Feature Flags**: Every CDP domain is represented by a Rust feature flag. You can optimize compile times by only compiling the domains your project needs:
```toml
# Compile only the page and dom domains
browser-protocol = { version = "0.1.3", default-features = false, features = ["page", "dom"] }
```
### Regenerating the Code
To regenerate the Rust modules from a local protocol file:
```bash
python scripts/generate_rust_code.py --name browser-protocol
```
---
## ⚖ License
Distributed under the MIT License. See `LICENSE` for more information.