132 lines
3.1 KiB
Markdown
132 lines
3.1 KiB
Markdown
# Terrace Rust
|
|
|
|
A Rust implementation of the Terrace language specification - a simple structured data syntax for configuration, content authoring, and DSLs.
|
|
|
|
## Installation
|
|
|
|
Add this to your `Cargo.toml`:
|
|
|
|
```toml
|
|
[dependencies]
|
|
terrace = "0.1"
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Basic Parsing
|
|
|
|
```rust
|
|
use terrace::{TerraceDocument, StringReader};
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
let content = r#"
|
|
config
|
|
database
|
|
host localhost
|
|
port 5432
|
|
server
|
|
port 3000
|
|
host 0.0.0.0
|
|
"#;
|
|
|
|
let reader = StringReader::new(content);
|
|
let mut doc = TerraceDocument::with_reader(reader);
|
|
|
|
while let Some(node) = doc.next().await {
|
|
println!("Level: {}, Head: '{}', Tail: '{}'",
|
|
node.level(), node.head(), node.tail());
|
|
}
|
|
}
|
|
```
|
|
|
|
### Working with Nodes
|
|
|
|
```rust
|
|
use terrace::{TerraceDocument, StringReader};
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
let content = "user john_doe active";
|
|
let reader = StringReader::new(content);
|
|
let mut doc = TerraceDocument::with_reader(reader);
|
|
|
|
if let Some(node) = doc.next().await {
|
|
assert_eq!(node.head(), "user");
|
|
assert_eq!(node.tail(), "john_doe active");
|
|
assert_eq!(node.level(), 0);
|
|
assert!(node.is("user"));
|
|
}
|
|
}
|
|
```
|
|
|
|
### Filtering and Mapping
|
|
|
|
```rust
|
|
use terrace::{TerraceDocument, StringReader};
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
let content = r#"
|
|
users
|
|
user alice active
|
|
user bob inactive
|
|
user charlie active
|
|
"#;
|
|
|
|
let reader = StringReader::new(content);
|
|
let doc = TerraceDocument::with_reader(reader);
|
|
|
|
// Find all active users
|
|
let active_users = doc.filter(|node| {
|
|
node.head() == "user" && node.tail().contains("active")
|
|
}).await;
|
|
|
|
println!("Found {} active users", active_users.len());
|
|
}
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### TerraceDocument
|
|
|
|
The main document iterator that parses Terrace documents.
|
|
|
|
- `new(reader, indent)` - Create a new document with custom indentation
|
|
- `with_reader(reader)` - Create a new document with default space indentation
|
|
- `next()` - Get the next node asynchronously
|
|
- `collect()` - Collect all nodes into a vector
|
|
- `filter(predicate)` - Filter nodes based on a predicate
|
|
- `find(predicate)` - Find the first node matching a predicate
|
|
- `map(mapper)` - Transform nodes using a mapper function
|
|
|
|
### TerraceNode
|
|
|
|
Represents a single line/node in a Terrace document.
|
|
|
|
- `head()` - Get the first word of the line
|
|
- `tail()` - Get everything after the first space
|
|
- `content()` - Get the content after indentation
|
|
- `level()` - Get the indentation level
|
|
- `line_number()` - Get the line number
|
|
- `is(value)` - Check if head matches a value
|
|
- `is_empty()` - Check if the line is empty
|
|
- `raw(offset)` - Get raw content from an offset
|
|
|
|
### Readers
|
|
|
|
- `StringReader` - Read from a string or vector of strings
|
|
- `AsyncReader` - Read from any async source
|
|
|
|
## Features
|
|
|
|
- **Async/Await Support**: Built with Tokio for asynchronous processing
|
|
- **Streaming**: Process large documents without loading everything into memory
|
|
- **Flexible Input**: Support for strings, files, and custom readers
|
|
- **Type Safe**: Full type safety with Rust's type system
|
|
- **Zero-Copy**: Efficient parsing with minimal allocations
|
|
|
|
## License
|
|
|
|
MIT
|