Terrace/packages/rust/docs/reader-api.inc.tce
Joshua Bemenderfer 9d9757e868 Updates.
2025-09-08 16:24:38 -04:00

186 lines
5.5 KiB
Plaintext

Heading 2 Reader API
class mt-12
Markdown
The [Document API](#document-api) requires `Reader` implementations to iterate through lines
in a document. A reader is any type that implements the `Reader` trait, which provides
an async method to read the next line from a source.
Terrace provides built-in readers for common use cases, but you can implement the trait
for your own custom sources.
Heading 3 Reader Trait
class mb-4 mt-12
Markdown
The Reader trait defines the interface for reading lines from a document source.
Implement this trait to create custom readers for different input sources.
CodeBlock rust
// Trait Definition
#[async_trait::async_trait]
pub trait Reader {
/// Read the next line from the source.
/// Returns None if there are no more lines.
async fn read_line(&mut self) -> io::Result<Option<String>>;
}
Heading 3 StringReader
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| source | impl Into<StringReaderSource> | The source content as a string or vector of strings.
| **@returns** | [StringReader](#string-reader) | A reader that iterates over the lines in the source.
A reader that reads from a string or vector of strings. This is the most common reader
for parsing Terrace documents from memory.
CodeBlock rust
// Struct Definition
pub struct StringReader {
// Implementation details...
}
// Constructor
pub fn new(source: impl Into<StringReaderSource>) -> Self
// Import Path
use terrace::readers::StringReader;
// Usage
// From a string
let reader = StringReader::new("line1\nline2\nline3");
// From a vector of strings
let reader = StringReader::new(vec!["line1", "line2", "line3"]);
// From a string slice
let reader = StringReader::new("line1\nline2\nline3");
Heading 3 AsyncReader
class mb-4 mt-12
Markdown
| Parameter | Type | Description
| -------------- | --------------------- | -----------------------------------------------------------------------
| reader | R | Any async reader that implements AsyncRead.
| **@returns** | [AsyncReader](#async-reader)<R> | A reader that reads lines from an async source.
A reader that reads from any async source that implements the `AsyncRead` trait.
This is useful for reading from files, network streams, or other async sources.
CodeBlock rust
// Struct Definition
pub struct AsyncReader<R> {
// Implementation details...
}
// Constructor
pub fn new(reader: R) -> Self
// Import Path
use terrace::readers::AsyncReader;
use tokio::fs::File;
// Usage
let file = File::open("document.tce").await?;
let reader = AsyncReader::new(file);
// Can also be used with other async sources
use tokio::io::BufReader;
let buffered = BufReader::new(file);
let reader = AsyncReader::new(buffered);
Heading 3 Custom Reader Implementation
class mb-4 mt-12
Markdown
You can implement the Reader trait for your own custom sources. This allows you
to read from databases, APIs, or any other source of line-based data.
CodeBlock rust
// Custom Reader Example
use async_trait::async_trait;
use std::io;
use terrace::readers::Reader;
struct DatabaseReader {
connection: DatabaseConnection,
query: String,
current_row: usize,
}
#[async_trait]
impl Reader for DatabaseReader {
async fn read_line(&mut self) -> io::Result<Option<String>> {
// Fetch next row from database
match self.connection.fetch_row(&self.query, self.current_row).await {
Ok(Some(row)) => {
self.current_row += 1;
Ok(Some(format!("{} {}", row.key, row.value)))
}
Ok(None) => Ok(None),
Err(e) => Err(io::Error::new(io::ErrorKind::Other, e)),
}
}
}
// Usage
let db_reader = DatabaseReader {
connection: connect_to_db().await?,
query: "SELECT key, value FROM config".to_string(),
current_row: 0,
};
let mut doc = TerraceDocument::with_reader(db_reader);
while let Some(node) = doc.next().await {
println!("{}: {}", node.head(), node.tail());
}
Heading 3 Reader Trait Implementation Details
class mb-4 mt-12
Markdown
When implementing the Reader trait, follow these guidelines:
- Return `Ok(Some(line))` for each line of content
- Return `Ok(None)` when there are no more lines
- Return `Err(error)` if an I/O error occurs
- Lines should not include trailing newlines
- The reader should be mutable to track state between calls
CodeBlock rust
// Complete Reader Implementation Example
use async_trait::async_trait;
use std::io;
use terrace::readers::Reader;
struct VecReader {
lines: Vec<String>,
index: usize,
}
impl VecReader {
fn new(lines: Vec<String>) -> Self {
Self { lines, index: 0 }
}
}
#[async_trait]
impl Reader for VecReader {
async fn read_line(&mut self) -> io::Result<Option<String>> {
if self.index >= self.lines.len() {
return Ok(None);
}
let line = self.lines[self.index].clone();
self.index += 1;
Ok(Some(line))
}
}
// Usage
let lines = vec![
"config".to_string(),
" database".to_string(),
" host localhost".to_string(),
];
let reader = VecReader::new(lines);
let mut doc = TerraceDocument::with_reader(reader);