use alloc::boxed::Box;
use alloc::vec::Vec;
use core::fmt;
use core::future::Future;
use core::pin::Pin;
use crate::AnyView;
#[derive(Debug, Clone, Copy)]
pub struct RenderSize {
pub width: f32,
pub height: f32,
}
impl RenderSize {
#[must_use]
pub const fn new(width: f32, height: f32) -> Self {
Self { width, height }
}
}
#[derive(Debug)]
pub struct RenderResult {
pub rgba_data: Vec<u8>,
pub width: u32,
pub height: u32,
}
pub trait CustomViewRenderer: 'static {
fn render_to_rgba(&self, view: AnyView, size: RenderSize)
-> impl Future<Output = RenderResult>;
}
trait CustomViewRendererImpl: 'static {
fn render_to_rgba<'a>(
&'a self,
view: AnyView,
size: RenderSize,
) -> Pin<Box<dyn 'a + Future<Output = RenderResult>>>;
}
impl<T: CustomViewRenderer> CustomViewRendererImpl for T {
fn render_to_rgba<'a>(
&'a self,
view: AnyView,
size: RenderSize,
) -> Pin<Box<dyn 'a + Future<Output = RenderResult>>> {
Box::pin(CustomViewRenderer::render_to_rgba(self, view, size))
}
}
pub struct ViewRenderer(Box<dyn CustomViewRendererImpl>);
impl ViewRenderer {
pub fn new<T: CustomViewRenderer>(renderer: T) -> Self {
Self(Box::new(renderer))
}
#[allow(clippy::future_not_send)]
pub async fn render(&self, view: AnyView, size: RenderSize) -> RenderResult {
self.0.render_to_rgba(view, size).await
}
}
impl fmt::Debug for ViewRenderer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ViewRenderer").finish_non_exhaustive()
}
}