judge_framework/frontend/
render.rs

1use chromiumoxide::{
2    cdp::browser_protocol::page::{CaptureScreenshotFormat, CaptureScreenshotParams},
3    handler::viewport::Viewport,
4    page::ScreenshotParams,
5    Browser, BrowserConfig,
6};
7use futures_util::StreamExt as _;
8
9use super::Result;
10
11pub async fn render(code: &str, width: u32, height: u32) -> Result<Vec<u8>> {
12    let viewport = Viewport {
13        width,
14        height,
15        ..Default::default()
16    };
17
18    let config = BrowserConfig::builder()
19        .viewport(viewport)
20        .no_sandbox()
21        .build()
22        .map_err(chromiumoxide::error::CdpError::msg)?;
23
24    let (mut browser, mut handler) = Browser::launch(config).await.unwrap();
25
26    let handler = tokio::task::spawn(async move {
27        while let Some(h) = handler.next().await {
28            if h.is_err() {
29                break;
30            }
31        }
32    });
33
34    let page = browser.new_page("about:blank").await?;
35    page.set_content(code).await?;
36
37    let image_buffer = page
38        .screenshot(ScreenshotParams {
39            cdp_params: CaptureScreenshotParams {
40                format: Some(CaptureScreenshotFormat::Png),
41                ..Default::default()
42            },
43            ..Default::default()
44        })
45        .await?;
46
47    let _ = browser.close().await;
48    let _ = handler.await;
49
50    Ok(image_buffer)
51}