Skip to main content

panes/
adapter.rs

1use std::sync::Arc;
2
3use crate::diff::LayoutDiff;
4use crate::overlay::{AnchorFailure, OverlayId};
5use crate::resolver::ResolvedLayout;
6use crate::runtime::{Frame, LayoutRuntime};
7
8/// Shared adapter-frame shell for renderer backends.
9///
10/// Captures the runtime-vs-stateless duality that every adapter crate needs:
11/// runtime frames borrow the [`LayoutRuntime`] for diff access, while stateless
12/// frames own a [`ResolvedLayout`] directly. Renderer-specific rect conversion
13/// and helpers remain local to each adapter crate.
14pub struct AdapterFrame<'a> {
15    kind: AdapterFrameKind<'a>,
16}
17
18enum AdapterFrameKind<'a> {
19    Runtime { frame: Frame, rt: &'a LayoutRuntime },
20    Stateless { resolved: ResolvedLayout },
21}
22
23impl<'a> AdapterFrame<'a> {
24    /// Build from a runtime resolve result.
25    pub fn from_runtime(frame: Frame, rt: &'a LayoutRuntime) -> Self {
26        Self {
27            kind: AdapterFrameKind::Runtime { frame, rt },
28        }
29    }
30
31    /// Build from a stateless resolve result.
32    pub fn from_stateless(resolved: ResolvedLayout) -> Self {
33        Self {
34            kind: AdapterFrameKind::Stateless { resolved },
35        }
36    }
37
38    /// Access the resolved layout regardless of variant.
39    pub fn resolved(&self) -> &ResolvedLayout {
40        match &self.kind {
41            AdapterFrameKind::Runtime { frame, .. } => frame.layout(),
42            AdapterFrameKind::Stateless { resolved } => resolved,
43        }
44    }
45
46    /// Layout diff (panel IDs, not rects). `None` for stateless resolves.
47    pub fn diff(&self) -> Option<LayoutDiff<'_>> {
48        match &self.kind {
49            AdapterFrameKind::Runtime { rt, .. } => Some(rt.last_diff()),
50            AdapterFrameKind::Stateless { .. } => None,
51        }
52    }
53
54    /// Raw panes [`Frame`]. `None` for stateless resolves.
55    pub fn inner(&self) -> Option<&Frame> {
56        match &self.kind {
57            AdapterFrameKind::Runtime { frame, .. } => Some(frame),
58            AdapterFrameKind::Stateless { .. } => None,
59        }
60    }
61
62    /// Overlays that failed to anchor during the most recent resolve.
63    pub fn overlay_failures(&self) -> &[(OverlayId, Arc<str>, AnchorFailure)] {
64        self.resolved().overlay_failures()
65    }
66}