retroglyph_recorder/owned_cell.rs
1//! [`OwnedCell`], the owned counterpart to [`DrawCell`] that a capture source buffers instead of
2//! the borrowed original.
3
4use retroglyph_core::backend::DrawCell;
5use retroglyph_core::color::Tint;
6use retroglyph_core::grid::Pos;
7use retroglyph_core::tile::Tile;
8
9/// An owned copy of a single [`DrawCell`], the shape [`FrameRecorder`](crate::FrameRecorder)
10/// buffers instead of the borrowed original.
11///
12/// `DrawCell` borrows its grapheme text from the source [`Grid`](retroglyph_core::grid::Grid), so
13/// a capture that outlives one `draw_layers` call (every capture source in this crate) must copy
14/// it out immediately rather than defer to export time, when the grid it borrowed from has
15/// already moved on to the next frame. `grapheme` is the one field that costs an allocation here;
16/// everything else (`Tile`, [`Pos`], `layer`, [`Tint`]) is already `Copy`.
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct OwnedCell {
19 /// See [`DrawCell::layer`].
20 pub layer: u8,
21 /// See [`DrawCell::pos`].
22 pub pos: Pos,
23 /// See [`DrawCell::tile`].
24 pub tile: Tile,
25 /// See [`DrawCell::grapheme`]. Copied to an owned `String` (rather than something
26 /// reference-counted) since `DrawCell` exposes only a borrowed `&str`, not the `Arc<str>`
27 /// backends like [`Headless`](retroglyph_core::backend::Headless) keep internally, so there
28 /// is no cheaper handle available across the `Output` trait boundary to share instead.
29 pub grapheme: Option<String>,
30 /// See [`DrawCell::tint`].
31 pub tint: Tint,
32}
33
34impl From<DrawCell<'_>> for OwnedCell {
35 fn from(cell: DrawCell<'_>) -> Self {
36 Self {
37 layer: cell.layer,
38 pos: cell.pos,
39 tile: *cell.tile,
40 grapheme: cell.grapheme.map(str::to_owned),
41 tint: cell.tint,
42 }
43 }
44}