Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 5, 2025

Adds optional builder patterns for complex message types while maintaining backward compatibility with direct construction.

Changes

New message type:

  • InfoBlockMessage - displays titled multi-line information blocks
  • Implements OutputMessage trait, routes to stderr at Normal verbosity

Builder API:

  • StepsMessageBuilder - fluent API for constructing step lists
  • InfoBlockMessageBuilder - fluent API for constructing info blocks
  • Consuming pattern (methods take self) enables clean chaining
  • Factory methods: StepsMessage::builder(), InfoBlockMessage::builder()

Backward compatibility:

  • Added StepsMessage::new() and InfoBlockMessage::new() constructors
  • Existing direct struct construction continues to work
  • Updated UserOutput::info_block() to use new InfoBlockMessage internally

Usage

// Builder pattern - dynamic construction, readable
let steps = StepsMessage::builder("Next steps:")
    .add("Edit configuration")
    .add("Review settings")
    .build();

// Simple constructor - all data upfront
let steps = StepsMessage::new("Steps:", vec!["Step 1".to_string()]);

// Info blocks
let info = InfoBlockMessage::builder("Environment")
    .add_line("Name: production")
    .add_line("Status: running")
    .build();

Tests: 25 new tests covering fluent API, direct construction, empty builders, integration with UserOutput/JSON formatter, and backward compatibility.

Original prompt

This section details on the original issue you should resolve

<issue_title>Proposal 8: Builder Pattern for Complex Messages</issue_title>
<issue_description>## Overview

Add optional builder patterns for complex message types in the UserOutput module. This proposal introduces builders that provide a fluent API for constructing complex messages while maintaining backward compatibility with simple direct construction.

Specification

See detailed specification: docs/issues/139-builder-pattern-for-complex-messages.md

Goals

  • Create builder pattern for StepsMessage with fluent API
  • Create builder pattern for InfoBlockMessage with fluent API
  • Maintain backward compatibility with simple constructors
  • Enable future extensibility with optional parameters
  • Provide ergonomic API for common use cases
  • Document when to use builders vs simple constructors

Implementation Plan

Phase 1: StepsMessageBuilder Implementation (1 hour)

  • Create StepsMessageBuilder struct
  • Implement new(), add(), and build() methods
  • Add StepsMessage::builder() convenience method
  • Keep existing StepsMessage::new() constructor

Phase 2: InfoBlockMessageBuilder Implementation (1 hour)

  • Create InfoBlockMessageBuilder struct
  • Implement new(), add_line(), and build() methods
  • Add InfoBlockMessage::builder() convenience method

Phase 3: Testing (1.5 hours)

  • Add tests for fluent API usage
  • Add tests for direct construction (ensure backward compatibility)
  • Add tests for empty builders
  • Add integration tests showing formatting with builders

Phase 4: Documentation and Quality (30 minutes)

  • Update module documentation with builder examples
  • Document when to use builders vs simple constructors
  • Run ./scripts/pre-commit.sh and fix any issues

Total Estimated Time: 4 hours

Acceptance Criteria

Functional Requirements

  • StepsMessageBuilder provides fluent API for step messages
  • InfoBlockMessageBuilder provides fluent API for info blocks
  • Simple constructors remain available and unchanged
  • Builders integrate seamlessly with OutputMessage trait
  • Builder pattern is consuming (not mutating)

API Design Requirements

  • Builder API is ergonomic and intuitive
  • Method names are clear and follow Rust conventions
  • builder() and new() methods coexist for different use cases

Testing Requirements

  • Unit tests cover fluent API construction
  • Tests verify backward compatibility with simple constructors
  • Tests cover edge cases (empty builders, single item, many items)

Quality Requirements

  • Pre-commit checks pass: ./scripts/pre-commit.sh
  • Builder pattern follows Rust idioms
  • No clippy warnings for builder implementation

Related

Labels

enhancement, phase-2, user-output, P2

Priority

P2 (Phase 2 - Polish & Extensions)

Estimated Effort

4 hours
</issue_description>

Comments on the Issue (you are @copilot in this section)

@josecelano **Parent Epic**: #102 - User Output Architecture Improvements

This issue is part of Phase 2: Polish & Extensions of the User Output Architecture refactoring.</comment_new>


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

Co-authored-by: josecelano <58816+josecelano@users.noreply.github.com>
@josecelano
Copy link
Member

@copilot the linting workflow is failing:

2025-11-05T08:17:00.141815Z  INFO rustfmt: Running Rust formatter check...

2025-11-05T08:17:00.602689Z ERROR rustfmt: Rust formatting check failed. Run 'cargo fmt' to fix formatting.
2025-11-05T08:17:00.602730Z ERROR torrust_linting::cli: Rust formatting failed: Rust formatting check failed
2025-11-05T08:17:00.602749Z  INFO shellcheck: Running ShellCheck on shell scripts...
2025-11-05T08:17:00.637406Z  INFO shellcheck: Found 7 shell script(s) to check
Error: Some linters failed
2025-11-05T08:17:01.266337Z  INFO shellcheck: shellcheck passed
2025-11-05T08:17:01.266376Z ERROR torrust_linting::cli: Some linters failed
Error: Process completed with exit code 1.

Co-authored-by: josecelano <58816+josecelano@users.noreply.github.com>
Copilot AI changed the title [WIP] Add builder pattern for complex messages in UserOutput module Add builder pattern for StepsMessage and InfoBlockMessage Nov 5, 2025
Copilot AI requested a review from josecelano November 5, 2025 08:29
Copilot finished work on behalf of josecelano November 5, 2025 08:29
Copy link
Contributor Author

Copilot AI commented Nov 5, 2025

@copilot the linting workflow is failing:

...

The formatting issue was already fixed in commit 1a3079b. The CI failure you saw was from commit 287f106 (before the formatting fix).

I've verified that the current HEAD passes all linting checks including rustfmt on both stable and nightly toolchains:

  • cargo +stable fmt -- --check passes
  • cargo +nightly fmt -- --check passes
  • cargo run --bin linter all passes all checks

The formatting is correct now.

Copilot finished work on behalf of josecelano November 5, 2025 08:40
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 1a3079b

@josecelano josecelano marked this pull request as ready for review November 5, 2025 09:07
@josecelano josecelano merged commit d6aba23 into main Nov 5, 2025
52 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.

Proposal 8: Builder Pattern for Complex Messages

2 participants