libmudtelnet-rs 2.0.9

Robust, event-driven Telnet (RFC 854) parser for MUD clients with GMCP, MSDP, MCCP support and zero-allocation hot paths
Documentation
# libmudtelnet Development Guide (AI Assistant Edition)

1. TL;DR for AI Assistants
- Goal: Maintain a simple, robust, idiomatic Rust Telnet (RFC 854) parser with strong real-world compatibility.
- Do:
  - Keep changes small and focused.
  - Favor clarity over cleverness.
  - Preserve behavior/API compatibility with libtelnet-rs unless explicitly justified (see §5).
  - Optimize only hot paths, measured by benchmarks (see §6, §8).
  - Add tests for new behaviors; fuzz regularly (see §8).
- Don't:
  - Over-engineer abstractions or anticipate future protocols (YAGNI).
  - Introduce panics for malformed data—be defensive and lenient.
  - Allocate in hot paths unless unavoidable and measured.
- Workflow: Implement → test (unit/compat/fuzz) → bench → clippy/fmt → PR (see §9–§12).

2. Purpose and Scope
- What this is: A low-level, event-driven Telnet protocol library for MUD clients that implements RFC 854 and provides robust parsing with minimal allocations.
- What this is not:
  - Higher-level protocols (GMCP, MSDP, MCCP) or ANSI color parsing.
  - Connection/TCP management, UI, scripting, session management.
- Design priorities: Simplicity, robustness, compatibility, performance in hot paths, idiomatic Rust.

3. Non-Negotiable Engineering Principles
- Simple: Prefer the clearest working solution; avoid cleverness.
- Robust: Handle malformed input defensively; never panic on input.
- Idiomatic Rust: Follow conventions and leverage types; keep public APIs clean and documented.
- No Overengineering: Build for current needs; avoid speculative abstractions.
- Test-Driven Behavior: Every change comes with tests to lock behavior (see §8).
- Compatibility-Aware: Behavior/API must remain consistent unless a justified policy update is made (see §5).
- Performance-Responsible: Optimize only when measured and justified (see §6).

4. Architecture and Protocol Coverage
- High-level flow:
  - Client application reads/writes TCP bytes.
  - libmudtelnet parses incoming bytes and emits events for the client.
- Core modules:
  - Parser (src/lib.rs): Stateful, event-driven parsing; minimal allocations using bytes::Bytes/BytesMut.
  - Events (src/events.rs): TelnetEvents enum; Data, Negotiation (WILL/WONT/DO/DONT), Subnegotiation, etc.
  - Protocol (src/telnet.rs): Command constants (IAC/WILL/WONT/DO/DONT/SB/SE), option codes.
  - Compatibility (src/compatibility.rs): Option support table and negotiation state.
- Protocol coverage:
  - IAC (255) handling, including proper doubling for data.
  - WILL/WONT, DO/DONT negotiations for option codes 0–255.
  - Subnegotiation: SB <option> <data> SE, with correct IAC escaping in data.
- Edge cases handled:
  - Truncated subnegotiations (e.g., IAC SB IAC SE).
  - Unescaped SE bytes appearing in data.
  - Multiple IAC escaping sequences (IAC IAC IAC IAC).
  - Non-standard server quirks and partial/incomplete sequences.
- For performance/memory rules, see §6. For compatibility guarantees, see §5.

5. Compatibility Policy
- Standards compliance: RFC 854 is the ground truth for base protocol behavior.
- Reference implementation: Maintain behavior/API compatibility with libtelnet-rs where feasible and beneficial to users.
- Behavior guarantees:
  - Event semantics are stable; changes must be backward compatible or guarded behind explicit feature flags.
  - Negotiation state management must not regress against the compatibility test suite.
  - Malformed inputs are handled gracefully without crashes or UB.
- API stability:
  - Avoid breaking public APIs; if necessary, follow semver and deprecate with clear migration notes.
- Test gating:
  - All changes must pass the compatibility tests (see §8).
  - Document any intentional deviations from libtelnet-rs with rationale in CHANGELOG and tests.

6. Performance and Memory Policy
- Goals:
  - Zero or minimal allocations in hot parsing paths.
  - Use bytes::Bytes/BytesMut to avoid copies and enable zero-copy slices where possible.
  - Avoid intermediate String conversions; operate on &[u8] slices.
- Memory management:
  - Reuse buffers; allow growth when needed but avoid thrashing.
  - Keep parser state minimal; no unnecessary heap allocations in tight loops.
  - Maintain optional no_std compatibility (no default features).
- Measurement and thresholds:
  - Benchmark critical paths before and after changes (see §8).
  - No performance regression beyond noise (agree on threshold ~3–5%) without explicit justification.
- Optimization workflow:
  - Profile → hypothesize → implement → benchmark → keep or revert.
  - If an optimization increases complexity, ensure the gain is material and documented.

7. Usage Quickstart
- Add dependency (example Cargo.toml entry):
  - libmudtelnet = { path = "../libmudtelnet" }
- Basic parser loop:
  - use libmudtelnet::{Parser, events::TelnetEvents};
  - let mut parser = Parser::new();
  - let events = parser.receive(&socket_bytes);
  - for ev in events { match ev { TelnetEvents::DataReceive(data) => { /* use data */ }, TelnetEvents::Negotiation(n) => { /* handle */ }, _ => {} } }
- Sending:
  - let bytes = parser.send_text("user command\r\n");
  - let reply = parser.negotiate(&some_negotiation_event);
- See §4 for protocol coverage and event semantics.

8. Testing and Quality Gates
- Test types and locations:
  - Unit tests (tests/): Parsing, IAC escaping/unescaping, negotiation state, edge cases.
  - Property-based testing: Round-trip invariants, escaping invariants, event/data partitioning.
  - Fuzzing (fuzz/): parser_receive, parser_escape; ensure no panics/UB on random inputs.
  - Compatibility tests (compat/): Behavior parity with libtelnet-rs on shared cases.
  - Benchmarks (compat/bench or dedicated benches): Detect regressions in hot paths.
- Canonical commands:
  - Build/test:
    - cargo build
    - cargo test
    - cargo test --release
    - cargo test --no-default-features
  - Lint/format:
    - cargo fmt
    - cargo clippy -- -D warnings
  - Fuzz (requires cargo-fuzz):
    - cargo install cargo-fuzz
    - cd fuzz && cargo fuzz run parser_receive
    - cd fuzz && cargo fuzz run parser_escape
    - cargo fuzz cmin parser_receive
  - Bench:
    - cd compat && cargo bench
- Quality gates for merging:
  - All tests (unit/property/compat) pass on debug and release.
  - No new panics on fuzz targets within reasonable runs (e.g., 60–120s).
  - No significant benchmark regressions (>5%) without documented justification.
  - clippy passes with -D warnings; code is formatted.
  - Public API changes are documented and reviewed for compatibility (see §5).

9. Developer Workflow
- Day-to-day:
  - Implement small, focused changes.
  - Write/extend tests first or alongside implementation (see §8).
  - Run cargo test; fix regressions early.
  - Fuzz locally on changed areas; minimize failing inputs if found.
  - Benchmark if your changes touch parsing hot paths.
- Debugging tips:
  - Add targeted logging behind a feature flag if needed; remove before merging or keep behind the flag.
  - Reproduce fuzz failures with minimized cases (cargo fuzz cmin ...).
- Adding protocol behaviors:
  - Keep behavior aligned with RFC 854; extend events or options conservatively.
  - Update compatibility tables and tests together (see §5, §8).
- For commands and acceptance criteria, refer to §8.

10. Contribution Standards
- Conventional Commits:
  - feat:, fix:, docs:, refactor:, test:, perf:, chore:
- Code style:
  - cargo fmt before commit; cargo clippy -- -D warnings must pass.
  - Document public APIs; prefer clear names and small modules.
- Naming conventions:
  - Modules/files: snake_case, singular (e.g., protocol.rs, state_machine.rs).
  - Types: PascalCase (e.g., TelnetEvents, ConnectionState).
  - Functions/vars: snake_case (e.g., parse_message, connection_count).
- Commit hygiene:
  - Keep commits atomic; no git commit --amend in shared history.
  - Reference issues when applicable.
- Reviews:
  - Discuss trade-offs explicitly; justify complexity with measured benefit.

11. References
- Specifications:
  - RFC 854 – Telnet Protocol
  - RFC 855 – Telnet Option Specifications
  - RFC 1073 – NAWS (Window Size)
  - RFC 1091 – Terminal Type
- Libraries/Docs:
  - libtelnet-rs (reference behavior)
  - bytes crate docs (Bytes/BytesMut)
  - Rust Fuzz Book
- Tools:
  - Wireshark (protocol byte-level inspection)
  - Real MUD servers (compatibility validation)

12. Pre-PR Checklist
- Behavior & API
  - [ ] Changes align with RFC 854 and Compatibility Policy (§5).
  - [ ] No breaking public API changes, or semver/deprecation plan documented.
- Tests & Fuzz
  - [ ] Unit/integration tests added/updated for all new behavior.
  - [ ] Fuzz targets run without new crashes; minimized cases added as tests if relevant.
  - [ ] Compatibility tests pass; deviations documented and justified.
- Performance
  - [ ] Benchmarks run; no significant regressions (>5%) unless justified.
  - [ ] No unnecessary allocations added to hot paths; Bytes/BytesMut used where appropriate (§6).
- Quality
  - [ ] cargo fmt run; cargo clippy -- -D warnings passes.
  - [ ] Public APIs and behaviors documented; changelog notes (if needed).
- Ready to Merge
  - [ ] Commit messages follow Conventional Commits and are atomic.
  - [ ] Trade-offs and rationale captured in PR description.