# Example

This repository demonstrates modern, idiomatic Rust through two parts:

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`.

---

## 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

```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      |

### 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}"),
    }
}
```

---

## 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+](https://docs.rs/tokio) (for async runtime)

---

## Project Structure

```text
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
