use std::sync::Arc;
#[cfg(feature = "browser")]
pub struct BrowserApi {
inner: tokio::sync::OnceCell<Arc<oxibrowser_core::Browser>>,
config: Option<oxibrowser_core::BrowserConfig>,
}
#[cfg(feature = "browser")]
impl Clone for BrowserApi {
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
config: self.config.clone(),
}
}
}
#[cfg(feature = "browser")]
impl BrowserApi {
pub fn from_config(config: &oxibrowser_core::BrowserConfig) -> Self {
Self {
inner: tokio::sync::OnceCell::new(),
config: Some(config.clone()),
}
}
pub fn new(browser: Arc<oxibrowser_core::Browser>) -> Self {
let cell = tokio::sync::OnceCell::new();
match cell.set(browser) {
Ok(()) => {}
Err(_) => unreachable!("OnceCell was just created"),
}
Self {
inner: cell,
config: None,
}
}
pub async fn browser(&self) -> anyhow::Result<&Arc<oxibrowser_core::Browser>> {
self.inner
.get_or_try_init(|| async {
let config = self
.config
.as_ref()
.ok_or_else(|| anyhow::anyhow!("BrowserApi has no config and was not pre-initialized"))?;
let browser = oxibrowser_core::Browser::new(config.clone())
.await
.map_err(|e| anyhow::anyhow!("Failed to initialize browser engine: {}", e))?;
Ok(Arc::new(browser))
})
.await
}
pub async fn shutdown(&self) -> anyhow::Result<()> {
if let Some(browser) = self.inner.get() {
browser.close().await?;
}
Ok(())
}
}
#[cfg(feature = "browser")]
impl Default for BrowserApi {
fn default() -> Self {
Self {
inner: tokio::sync::OnceCell::new(),
config: None,
}
}
}
#[cfg(not(feature = "browser"))]
pub struct BrowserApi;
#[cfg(not(feature = "browser"))]
impl Default for BrowserApi {
fn default() -> Self {
BrowserApi
}
}