Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 4, 2025

Channel routing (stdout vs stderr) in UserOutput was done via runtime pattern matching. This adds compile-time guarantees using newtype wrappers to prevent accidental channel confusion.

Changes

Type-Safe Wrappers (private)

  • StdoutWriter and StderrWriter newtypes wrapping Box<dyn Write + Send + Sync>
  • Methods: new(), write_line(), writeln()
  • Zero-cost abstraction via newtype pattern

UserOutput Structure

  • Fields changed from Box<dyn Write> to typed wrappers (stdout: StdoutWriter, stderr: StderrWriter)
  • Private helpers write_to_stdout() and write_to_stderr() for type-safe dispatch
  • write() method now uses compile-time channel routing instead of runtime matching

Example

Before (runtime dispatch):

let writer = match message.channel() {
    Channel::Stdout => &mut self.stdout_writer,
    Channel::Stderr => &mut self.stderr_writer,
};
write!(writer, "{formatted}").ok();

After (type-safe dispatch):

match message.channel() {
    Channel::Stdout => self.write_to_stdout(&formatted),
    Channel::Stderr => self.write_to_stderr(&formatted),
}

Compatibility

  • All existing tests pass without modification
  • Public API unchanged
  • Added 8 tests demonstrating compile-time safety

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 192.0.2.1
    • Triggering command: ssh -i /nonexistent/key -p 22 -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=5 testuser@192.0.2.1 echo &#39;SSH connected&#39; (packet block)
    • Triggering command: ssh -i /nonexistent/key -p 22 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5 testuser@192.0.2.1 echo &#39;SSH connected&#39; (packet block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Type-Safe Channel Routing for User Output</issue_title>
<issue_description>## Overview

Add compile-time type safety for channel routing (stdout vs stderr) in the UserOutput module by introducing newtype wrappers for writers. Currently, channel routing is done with runtime pattern matching which, while functional, doesn't provide compile-time guarantees that messages go to the correct channel.

This refactoring introduces StdoutWriter and StderrWriter newtype wrappers that make channel routing explicit in the type system, preventing accidental channel confusion at compile time.

Specification

See detailed specification: docs/issues/135-type-safe-channel-routing-for-user-output.md

🏗️ Architecture Requirements

DDD Layer: Presentation
Module Path: src/presentation/user_output.rs
Pattern: Type-safe wrappers using newtype pattern

Module Structure Requirements

Architectural Constraints

  • Zero-cost abstraction using newtype pattern
  • No runtime overhead compared to current implementation
  • Preserve existing error handling behavior
  • Error handling follows project conventions (see docs/contributing/error-handling.md)

Anti-Patterns to Avoid

  • ❌ Exposing writer wrappers in public API unnecessarily
  • ❌ Adding runtime checks when compile-time safety is available
  • ❌ Breaking existing test infrastructure

Implementation Plan

Phase 1: Create Newtype Wrappers (30 minutes)

  • Task 1.1: Create StdoutWriter newtype struct with documentation
  • Task 1.2: Create StderrWriter newtype struct with documentation
  • Task 1.3: Implement new() constructor for both wrappers
  • Task 1.4: Implement write_line() method for both wrappers
  • Task 1.5: Add unit tests for wrapper creation and writing

Phase 2: Update UserOutput Structure (45 minutes)

  • Task 2.1: Update UserOutput struct fields to use typed wrappers
  • Task 2.2: Add private helper methods write_to_stdout() and write_to_stderr()
  • Task 2.3: Update all constructors to wrap writers in typed newtype
  • Task 2.4: Update write() method to use typed writer helpers
  • Task 2.5: Verify all existing public methods compile and work correctly

Phase 3: Update Tests (30 minutes)

  • Task 3.1: Update test infrastructure to work with newtype wrappers
  • Task 3.2: Add tests for type-safe channel routing
  • Task 3.3: Verify all existing tests pass without modification
  • Task 3.4: Add test cases demonstrating compile-time safety benefits

Phase 4: Documentation and Quality (30 minutes)

  • Task 4.1: Update module documentation to mention type-safe routing
  • Task 4.2: Add code examples showing type safety benefits
  • Task 4.3: Run pre-commit checks and fix any issues
  • Task 4.4: Verify documentation builds correctly

Acceptance Criteria

Note for Contributors: These criteria define what the PR reviewer will check. Use this as your pre-review checklist before submitting the PR to minimize back-and-forth iterations.

Quality Checks:

  • Pre-commit checks pass: ./scripts/pre-commit.sh
  • All tests pass: cargo test
  • Documentation builds: cargo doc --no-deps

Task-Specific Criteria:

  • StdoutWriter and StderrWriter newtype wrappers are implemented
  • Both wrappers have new() and write_line() methods
  • UserOutput struct uses typed wrappers instead of raw Box<dyn Write>
  • All constructors wrap raw writers in typed newtypes
  • Private helper methods write_to_stdout() and write_to_stderr() exist
  • The write() method uses typed helpers instead of direct writer access
  • All existing tests pass without modification
  • New tests demonstrate compile-time safety benefits
  • Module documentation is updated to reflect type-safe routing
  • Code examples show the benefits of the newtype pattern
  • No performance regression (zero-cost abstraction)
  • IDE autocomplete shows channel-specific methods

Related


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits November 4, 2025 19:53
Co-authored-by: josecelano <58816+josecelano@users.noreply.github.com>
Co-authored-by: josecelano <58816+josecelano@users.noreply.github.com>
Co-authored-by: josecelano <58816+josecelano@users.noreply.github.com>
Copilot AI changed the title [WIP] Add type-safe channel routing for UserOutput Add type-safe channel routing for UserOutput with newtype wrappers Nov 4, 2025
Copilot finished work on behalf of josecelano November 4, 2025 20:16
Copilot AI requested a review from josecelano November 4, 2025 20:16
Copy link
Member

@josecelano josecelano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK d24db0a

@josecelano josecelano marked this pull request as ready for review November 4, 2025 21:28
@josecelano josecelano merged commit 666149c into main Nov 4, 2025
51 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Type-Safe Channel Routing for User Output

2 participants