Skip to main content

ferroui_diagnostics/diagnostics/screenshots/
base_render_to_stream_handler.rs

1//! Port of `Diagnostics/Screenshots/BaseRenderToStreamHandler.cs`.
2
3use crate::diagnostics::{IScreenshotHandler, VisualExtensions};
4use ferroui_base::input::LocalBoxFuture;
5use ferroui_base::Ref;
6use ferroui_controls::Control;
7use std::io::Write;
8
9/// Base class for render Screenshto to stream
10///
11/// An abstract class upstream: an implementation supplies the stream
12/// ([`get_stream`](Self::get_stream)) and is an [`IScreenshotHandler`] whose `take` renders the
13/// control to that stream, as the non-virtual `Take` of the original does.
14pub trait BaseRenderToStreamHandler {
15    /// Get stream to write a screenshot to.
16    ///
17    /// Resolves to the stream to render the control to, or to `None` when there is none (the
18    /// screenshot is then not taken).
19    fn get_stream(&self, control: &Ref<Control>) -> LocalBoxFuture<std::io::Result<Option<Box<dyn Write>>>>;
20}
21
22impl<T: BaseRenderToStreamHandler> IScreenshotHandler for T {
23    fn take(&self, control: &Ref<Control>) -> LocalBoxFuture<std::io::Result<()>> {
24        let stream = self.get_stream(control);
25        let control = control.clone();
26        Box::pin(async move {
27            // `await using var output = await GetStream(control)`: the stream is released when
28            // the screenshot is written.
29            let output = stream.await?;
30            if let Some(mut output) = output {
31                control.render_to(&mut *output)?;
32                output.flush()?;
33            }
34            Ok::<(), std::io::Error>(())
35        })
36    }
37}