1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! Output port for rendering command output
//!
//! This module defines the [`Presenter`] trait, the output port in the hexagonal architecture. A
//! `Presenter` wraps command execution and controls the output lifecycle. The framework calls
//! [`present`] with the command future, and the presenter runs the command, optionally consuming
//! events from its event channel, and returns the command's result.
//!
//! Presenter adapters implement this trait to provide different rendering strategies. A stateless
//! adapter renders each event as it arrives; a stateful adapter queries a surface on each render
//! frame. The command's code is identical regardless of which adapter is in use.
//!
//! [`present`]: Presenter::present
use Future;
use Pin;
use async_trait;
pub use TerminalPresenter;
use crateCommandResult;
/// Output port for rendering command output
///
/// A `Presenter` wraps command execution and controls the output lifecycle. The framework
/// constructs a presenter with its dependencies (such as an [`EventReceiver`] and rendering
/// configuration), then calls [`present`] with the command future. The presenter runs the
/// command, optionally consuming events from its receiver, and returns the command's result.
///
/// `present` takes `self` by value because presentation is a one-shot operation. Each presenter
/// is constructed once, used once, and consumed. This encodes the "call once" invariant in the
/// type system and avoids interior mutability for resources like [`EventReceiver`] that require
/// exclusive access for reading.
///
/// The trait does not require [`Send`] or [`Sync`] because the presenter lives on the main task
/// and is never shared across threads.
///
/// # Examples
///
/// ```rust,ignore
/// use clawless::presenter::{Presenter, TerminalPresenter};
///
/// let presenter = TerminalPresenter::builder().receiver(receiver).build();
/// presenter.present(Box::pin(command_future)).await?;
/// ```
///
/// [`EventReceiver`]: clawless_core::event::EventReceiver
/// [`present`]: Presenter::present