2025-06-27 15:55:37 -04:00
|
|
|
|
# Example
|
2025-06-27 08:48:57 -04:00
|
|
|
|
|
2025-06-28 16:52:04 -04:00
|
|
|
|
This repository demonstrates modern, idiomatic Rust through two parts:
|
2025-06-27 08:48:57 -04:00
|
|
|
|
|
2025-06-28 16:52:04 -04:00
|
|
|
|
1. **Foundational Rust Examples** – covering core concepts like lifetimes,
|
|
|
|
|
error handling, async, and testing.
|
|
|
|
|
2. **Advanced Async Job Runner** – a trait-based, concurrent task execution
|
|
|
|
|
framework built using `tokio`.
|
2025-06-27 08:48:57 -04:00
|
|
|
|
|
2025-06-27 15:55:37 -04:00
|
|
|
|
---
|
|
|
|
|
|
2025-06-28 16:52:04 -04:00
|
|
|
|
## Part 1: Foundational Rust Examples
|
|
|
|
|
|
|
|
|
|
A lightweight collection of examples demonstrating essential Rust features,
|
|
|
|
|
without relying on external dependencies (except `tokio`).
|
2025-06-27 15:55:37 -04:00
|
|
|
|
|
|
|
|
|
### Concepts Covered
|
|
|
|
|
|
|
|
|
|
- Arrays and Iteration
|
|
|
|
|
- Lifetimes and Borrowing
|
|
|
|
|
- Error Handling with `Result`, `?`, and custom messages
|
|
|
|
|
- Async Programming using `#[tokio::main]`
|
|
|
|
|
- File I/O with the standard library
|
|
|
|
|
- Unit and async testing
|
|
|
|
|
|
|
|
|
|
### Key Functions
|
|
|
|
|
|
|
|
|
|
| Function | Description |
|
|
|
|
|
|------------------|--------------------------------------------------------|
|
|
|
|
|
| `longest` | Returns the longest string in a slice without copying. |
|
|
|
|
|
| `read_and_parse` | Reads a file and parses its content into an integer. |
|
|
|
|
|
| `run_tasks` | Demonstrates spawning and awaiting async tasks. |
|
|
|
|
|
|
|
|
|
|
### Testing
|
|
|
|
|
|
|
|
|
|
Includes both synchronous and asynchronous unit tests under a
|
|
|
|
|
`#[cfg(test)]` module.
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2025-06-28 16:52:04 -04:00
|
|
|
|
## Part 2: Advanced Async Job Runner
|
2025-06-27 15:55:37 -04:00
|
|
|
|
|
2025-06-28 16:52:04 -04:00
|
|
|
|
An extensible, asynchronous job system using:
|
|
|
|
|
|
|
|
|
|
- Trait objects
|
|
|
|
|
- Pinned futures (`Pin<Box<dyn Future>>`)
|
|
|
|
|
- Tokio’s `JoinSet` for concurrent execution
|
|
|
|
|
- Fully dynamic job management without macros
|
|
|
|
|
|
|
|
|
|
### Why It Matters
|
|
|
|
|
|
|
|
|
|
This system demonstrates:
|
|
|
|
|
- Manual implementation of async trait behavior (without `async_trait`)
|
|
|
|
|
- Advanced type management (`Box<dyn Trait>`, lifetimes, `Pin`)
|
|
|
|
|
- Idiomatic use of `tokio::task::JoinSet` for parallelism
|
|
|
|
|
|
|
|
|
|
### Architecture
|
|
|
|
|
|
|
|
|
|
#### `Job` Trait
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
pub trait Job: Send + Sync {
|
|
|
|
|
fn name(&self) -> &str;
|
|
|
|
|
fn run<'a>(&self) -> Pin<Box<dyn Future<Output = JobResult> + Send + 'a>>
|
|
|
|
|
where Self: Sync + 'a;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### `JobRunner` Struct
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
pub struct JobRunner {
|
|
|
|
|
jobs: Vec<Box<dyn Job>>
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Manages and runs jobs concurrently.
|
|
|
|
|
|
|
|
|
|
#### Built-In Jobs
|
|
|
|
|
|
|
|
|
|
| Job Type | Behavior |
|
|
|
|
|
|-----------|---------------------------|
|
|
|
|
|
| `FileJob` | (Planned) Reads from disk |
|
|
|
|
|
| `SleepJob`| Simulates a delay |
|
|
|
|
|
| `MathJob` | Performs a math task |
|
2025-06-27 15:55:37 -04:00
|
|
|
|
|
2025-06-28 16:52:04 -04:00
|
|
|
|
### Usage
|
|
|
|
|
|
|
|
|
|
```rust
|
|
|
|
|
let mut runner = JobRunner::new();
|
|
|
|
|
runner.add_job(FileJob::new());
|
|
|
|
|
runner.add_job(SleepJob::new());
|
|
|
|
|
runner.add_job(MathJob::new());
|
|
|
|
|
|
|
|
|
|
for (name, result) in runner.run_all().await {
|
|
|
|
|
match result {
|
|
|
|
|
Ok(msg) => println!("{name}: {msg}"),
|
|
|
|
|
Err(err) => eprintln!("{name}: {err}"),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
2025-06-27 15:55:37 -04:00
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
2025-06-28 16:52:04 -04:00
|
|
|
|
## Testing & Extending
|
|
|
|
|
|
|
|
|
|
You can add unit or integration tests using mock jobs to simulate both success and failure.
|
|
|
|
|
|
|
|
|
|
Ideas for extension:
|
|
|
|
|
- Make the Jobs actually do something
|
|
|
|
|
- Interjob communication using channels
|
|
|
|
|
- Create a QueueRunner that will run jobs in sequence
|
|
|
|
|
- Create a ParallelRunner that will run jobs concurrently (simple rename)
|
|
|
|
|
- Create a system that allows QueueRunners and ParallelRunners to be combined
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
2025-06-27 15:55:37 -04:00
|
|
|
|
|
|
|
|
|
## Requirements
|
|
|
|
|
|
|
|
|
|
- Rust 1.76+ (for full language support)
|
|
|
|
|
- [Tokio 1.37+](https://docs.rs/tokio) (for async runtime)
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Project Structure
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
src/
|
2025-06-28 16:52:04 -04:00
|
|
|
|
├── adv_async.rs # Advanced async JobRunner
|
|
|
|
|
├── basic.rs # Foundational examples
|
|
|
|
|
├── info.rs # Crate information from Cargo
|
|
|
|
|
├── lib.rs # Entry point for the library
|
2025-06-27 15:55:37 -04:00
|
|
|
|
```
|
|
|
|
|
|
2025-06-27 08:48:57 -04:00
|
|
|
|
|
2025-06-28 16:52:04 -04:00
|
|
|
|
|
2025-06-27 08:48:57 -04:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Copyright & License
|
|
|
|
|
|
2025-06-27 15:55:37 -04:00
|
|
|
|
Copyright 2025 Jason Travis Smith
|
2025-06-27 08:48:57 -04:00
|
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
you may not use this library except in compliance with the License.
|
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS
|