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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
//! Optional plain-text rendering surface for environments.
//!
//! [`AsciiRenderable`] is an **optional debug helper**, not a library
//! invariant (ADR-0013). The two visualisation products do not depend on it:
//! the live TUI is metrics-only and renders no env, and the post-run report
//! renders env playback from the structured `FamilyPayload` carried in each
//! `EpisodeRecord` frame. An env implements this trait only when a quick
//! grep-friendly text dump is useful — for logs, snapshot tests, or a
//! user-built env that wants the report's legacy `<pre>` fallback without
//! writing a structured payload adapter.
//!
//! The trait lives in `rlevo-core` (rather than `rlevo-environments`) so that
//! `rlevo-benchmarks` can still bound on it without a circular package dep.
//! It is not a supertrait of `Environment`.
use ;
/// An environment that can render itself as an ASCII string.
///
/// Optional (ADR-0013): implement it only for envs that want a text dump.
/// The [`AsciiRenderer`] delegates to [`render_ascii`](Self::render_ascii)
/// and returns the `String` as its `Frame`.
///
/// # Two projections
///
/// Two methods, two consumers:
///
/// - [`render_ascii`](Self::render_ascii) returns a plain `String` for logs,
/// snapshot tests, grep-friendly output, and the optional
/// `FrameRecord.ascii` slot. Every implementor must provide it.
/// - [`render_styled`](Self::render_styled) returns a
/// [`StyledFrame`] carrying colour and modifier hints for the report's
/// legacy `<pre>`/CSS-span fallback. The default impl wraps the plain text
/// as a single unstyled span, so implementors that only want the plain
/// projection compile without changes.
///
/// Override `render_styled` only when the text dump benefits from colour
/// cues. Use the project palette constants in [`super::palette`] rather than
/// raw [`super::Color`] values so that the accessibility contract
/// (hue-redundant signalling for hazard/goal semantics) is preserved.
/// A renderer that produces ASCII `String` frames.
///
/// Implements [`Renderer<E>`](super::Renderer) for any `E: AsciiRenderable`,
/// delegating to [`AsciiRenderable::render_ascii`]. Pair with
/// [`NullRenderer`](crate::render::NullRenderer) when rendering is
/// disabled so the call compiles away entirely.
///
/// # Example
///
/// ```no_run
/// use rlevo_core::render::{AsciiRenderable, AsciiRenderer, Renderer};
///
/// struct GridEnv { width: usize, height: usize }
///
/// impl AsciiRenderable for GridEnv {
/// fn render_ascii(&self) -> String {
/// (0..self.height)
/// .map(|_| ".".repeat(self.width))
/// .collect::<Vec<_>>()
/// .join("\n")
/// }
/// }
///
/// let env = GridEnv { width: 5, height: 3 };
/// let renderer = AsciiRenderer;
/// let frame: String = renderer.render(&env);
/// println!("{frame}");
/// ```
;