Really it doesn't have channels so the only advanced thing was the dynamic trait part. Pinning the futures is only real hard part to this module. The rest does show trait implementations on structs though which was something missing from the library before. Also, the project was turned into a library and the foundational examples were put into a basic module.
3.8 KiB
Example
This repository demonstrates modern, idiomatic Rust through two parts:
- Foundational Rust Examples – covering core concepts like lifetimes, error handling, async, and testing.
- Advanced Async Job Runner – a trait-based, concurrent task execution
framework built using
tokio
.
Part 1: Foundational Rust Examples
A lightweight collection of examples demonstrating essential Rust features,
without relying on external dependencies (except tokio
).
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.
Part 2: Advanced Async Job Runner
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
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
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 |
Usage
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}"),
}
}
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
Requirements
- Rust 1.76+ (for full language support)
- Tokio 1.37+ (for async runtime)
Project Structure
src/
├── adv_async.rs # Advanced async JobRunner
├── basic.rs # Foundational examples
├── info.rs # Crate information from Cargo
├── lib.rs # Entry point for the library
Copyright & License
Copyright 2025 Jason Travis Smith
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