Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .envrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export PATH="$PWD/javascript/packages/language-server/bin:$PATH"
export PATH="$PWD/javascript/packages/highlighter/bin:$PATH"
export PATH="$PWD/javascript/packages/stimulus-lint/bin:$PATH"
export PATH="$PWD/java/bin:$PATH"
export PATH="$PWD/rust/bin:$PATH"
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ templates/**/*.h.erb linguist-language=C
templates/**/*.java.erb linguist-language=Java
templates/**/*.js.erb linguist-language=JavaScript
templates/**/*.rb.erb linguist-language=Ruby
templates/**/*.rs.erb linguist-language=Rust
templates/**/*.ts.erb linguist-language=TypeScript

# Template-generated RBS files
Expand Down
1 change: 1 addition & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ rust:
- changed-files:
- any-glob-to-any-file:
- '**/*.rs'
- '**/*.rs.erb'
- '**/Cargo.toml'
- '**/Cargo.lock'

Expand Down
68 changes: 68 additions & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Rust

on:
push:
branches:
- main
pull_request:

permissions:
actions: read
contents: read

jobs:
build:
name: Build
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Rust
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
components: clippy

- name: Set up Rust Nightly (for rustfmt)
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: nightly
components: rustfmt

- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
workspaces: rust

- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true

- name: bundle install
run: bundle install

- name: Render Templates
run: bundle exec rake templates

- name: Compile Herb
run: bundle exec rake make

- name: Check Rust formatting
run: make format-check
working-directory: rust

- name: Clippy
run: make lint
working-directory: rust

- name: Build Rust
run: make build
working-directory: rust

- name: Run Rust tests
run: make test
working-directory: rust
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ javascript/packages/node/extension/nodes.h
lib/herb/ast/nodes.rb
lib/herb/errors.rb
lib/herb/visitor.rb
rust/src/ast/nodes.rs
rust/src/errors.rs
rust/src/nodes.rs
sig/serialized_ast_errors.rbs
sig/serialized_ast_nodes.rbs
src/ast_nodes.c
Expand All @@ -126,6 +129,10 @@ wasm/nodes.h
java/target/
java/.java_compiled

# Rust Build Artifacts
rust/target/
rust/Cargo.lock

# NX Monorepo
.nx/
.nx/cache
Expand Down
2 changes: 2 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ Metrics/ClassLength:
Metrics/ModuleLength:
Exclude:
- test/**/*.rb
- templates/**/*.rb

Metrics/BlockLength:
Max: 30
Expand All @@ -118,6 +119,7 @@ Metrics/PerceivedComplexity:
- lib/herb/project.rb
- lib/herb/engine.rb
- lib/herb/engine/**/*.rb
- templates/template.rb
- test/**/*.rb
- bin/**/*

Expand Down
8 changes: 8 additions & 0 deletions docs/.vitepress/config/theme.mts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ const defaultSidebar = [
{ text: "Reference", link: "/bindings/java/reference" },
],
},
{
text: "Rust",
collapsed: false,
items: [
{ text: "Installation", link: "/bindings/rust/" },
{ text: "Reference", link: "/bindings/rust/reference" },
],
},
{ text: "WebAssembly", link: "/projects/webassembly" },
],
},
Expand Down
1 change: 1 addition & 0 deletions docs/docs/bindings/java/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Herb provides official Java bindings through JNI (Java Native Interface) to the
> Herb also has bindings for:
> - [Ruby](/bindings/ruby/)
> - [JavaScript/Node.js](/bindings/javascript/)
> - [Rust](/bindings/rust/)

## Installation

Expand Down
1 change: 1 addition & 0 deletions docs/docs/bindings/javascript/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Herb supports both **browser** and **Node.js** environments with separate packag
> Herb also has bindings for:
> - [Ruby](/bindings/ruby/)
> - [Java](/bindings/java/)
> - [Rust](/bindings/rust/)

## Installation

Expand Down
1 change: 1 addition & 0 deletions docs/docs/bindings/ruby/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Herb is bundled and packaged up as a precompiled RubyGem and available to be ins
> Herb also has bindings for:
> - [JavaScript/Node.js](/bindings/javascript/)
> - [Java](/bindings/java/)
> - [Rust](/bindings/rust/)

## Installation

Expand Down
85 changes: 85 additions & 0 deletions docs/docs/bindings/rust/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
outline: deep
---

# Herb Rust Bindings

Herb provides official Rust bindings through FFI (Foreign Function Interface) to the C library, allowing you to parse HTML+ERB in Rust projects with native performance.

> [!TIP] More Language Bindings
> Herb also has bindings for:
> - [Ruby](/bindings/ruby/)
> - [JavaScript/Node.js](/bindings/javascript/)

## Installation

Add the dependency to your `Cargo.toml`:

:::code-group
```toml [Cargo.toml]
[dependencies]
herb = "0.7.5"
```
:::

Or use `cargo` to add the dependency to your project:

:::code-group
```shell
cargo add herb
```
:::

## Getting Started

Import the `herb` crate in your project:

:::code-group
```rust
use herb::{parse, lex};
```
:::

You are now ready to parse HTML+ERB in Rust.

### Basic Example

Here's a simple example of parsing HTML+ERB:

:::code-group
```rust
use herb::parse;

fn main() {
let source = "<h1><%= user.name %></h1>";

match parse(source) {
Ok(result) => {
println!("{}", result.tree_inspect());
}
Err(e) => {
eprintln!("Parse error: {}", e);
}
}
}
```
:::

### Lexing Example

You can also tokenize HTML+ERB source:

:::code-group
```rust
use herb::lex;

fn main() {
let source = "<h1><%= user.name %></h1>";
let result = lex(source);

for token in result.tokens() {
println!("{}", token.inspect());
}
}
```
:::
Loading
Loading