Restructure into a library crate with modular bot and irc

Split the single-binary crate into a reusable `rustbot` library (src/lib.rs)
plus a thin supervisor binary. The monolithic irc.rs and bot.rs become module
folders:

  irc/    message (wire parsing), connection (TCP/TLS transport), encoding
  bot/    mod (state + event loop), caps (IRCv3 cap negotiation + SASL),
          commands (message routing + command table)
  config  Config + layered loading, moved out of main.rs and bot.rs

main.rs is now just the per-network connect/reconnect supervisor over the
library API. Unit tests move out of the source files into tests/ integration
tests (config.rs, protocol.rs) that drive the public surface — prefix parsing
is now covered through Message::parse, and config layering through the new
public config::parse_str. Behavior is unchanged; no new dependencies.
This commit is contained in:
Jean Chevronnet 2026-07-29 15:38:55 +00:00
parent b9e95430f5
commit a15fb4f9a9
16 changed files with 1189 additions and 1116 deletions

View file

@ -5,20 +5,26 @@ protocol layer built to the [modern IRC client spec](https://modern.ircdocs.hors
## Structure
| File | Layer | Responsibility |
|---------------|------------------|-----------------------------------------------------------|
| `src/irc.rs` | protocol + I/O | Parse/serialize IRC messages (incl. IRCv3 tags), TCP transport |
| `src/bot.rs` | behavior | Registration, event loop, command handling |
| `src/main.rs` | wiring | Layered config, one connect/reconnect supervisor thread per network |
rustbot is a **library crate** (`src/lib.rs`) with a thin binary on top:
The layers are deliberately separable: `irc.rs` knows nothing about the bot, and
`bot.rs` knows nothing about how the process is launched.
| Path | Layer | Responsibility |
|-----------------|----------------|-------------------------------------------------------------------|
| `src/irc/` | protocol + I/O | `message` (parse IRCv3 wire format), `connection` (TCP/TLS transport), `encoding` (base64, server-time) |
| `src/bot/` | behavior | `mod` (state + event loop), `caps` (IRCv3 cap negotiation + SASL), `commands` (message routing + command table) |
| `src/config.rs` | configuration | Layered `Config`; multi-network `[section]` parsing |
| `src/lib.rs` | crate root | Ties the modules into the reusable `rustbot` library |
| `src/main.rs` | binary | Thin per-network connect/reconnect supervisor |
| `tests/` | tests | Integration tests (`config.rs`, `protocol.rs`) against the public API |
The layers are deliberately separable: `irc` knows nothing about the bot, `bot`
knows nothing about how the process is launched, and `main` only supervises.
Adding a command is usually a one-file change in `src/bot/commands.rs`.
## Build & run
```sh
cargo build # or: cargo build --release
cargo test # unit tests for the message parser
cargo test # integration tests in tests/ (config + protocol)
cargo run
```
@ -26,7 +32,7 @@ cargo run
Settings are layered, each overriding the previous:
1. **Built-in defaults** (`Config::default()` in `src/bot.rs`)
1. **Built-in defaults** (`Config::default()` in `src/config.rs`)
2. **A config file**`key = value`, see [`rustbot.conf`](rustbot.conf)
3. **Environment variables** — handy for one-off overrides