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}