use std::path::PathBuf;
pub use self::installation::BrowserFetcherInstallation;
pub use self::options::BrowserFetcherOptions;
use crate::render::chrome_fetcher::error::{FetcherError, Result};
use crate::render::chrome_fetcher::{
BrowserHost, BrowserKind, BrowserVersion, BuildInfo, Platform, Runtime,
};
mod installation;
mod options;
pub struct BrowserFetcher {
host: BrowserHost,
path: PathBuf,
platform: Platform,
kind: BrowserKind,
version: BrowserVersion,
}
impl BrowserFetcher {
pub fn new(options: BrowserFetcherOptions) -> Self {
Self {
host: options.host,
path: options.path,
platform: options.platform,
kind: options.kind,
version: options.version,
}
}
pub async fn fetch(&self) -> Result<BrowserFetcherInstallation> {
let build_info = self
.version
.resolve(self.kind, self.platform, &self.host)
.await?;
tracing::debug!(target: "crate::render::chrome_fetcher::fetch", build_info = ?build_info, "Build info");
if !self.local(&build_info).await {
self.download(&build_info).await?;
}
Ok(self.installation(build_info))
}
async fn local(&self, build_info: &BuildInfo) -> bool {
let folder_path = self.folder_path(build_info);
let executable_path = self
.kind
.executable(self.platform, build_info, &folder_path);
Runtime::exists(&executable_path).await
}
async fn download(&self, build_info: &BuildInfo) -> Result<()> {
let url = self
.kind
.download_url(self.platform, build_info, &self.host);
let folder_path = self.folder_path(build_info);
let archive_path = folder_path.with_extension("zip");
tracing::debug!(target: "crate::render::chrome_fetcher::download", url = %url, archive_path = ?archive_path, "Downloading browser");
Runtime::download_file(&url, &archive_path)
.await
.map_err(FetcherError::DownloadFailed)?;
Runtime::unzip(archive_path, folder_path)
.await
.map_err(FetcherError::InstallFailed)?;
Ok(())
}
fn folder_path(&self, build_info: &BuildInfo) -> PathBuf {
let mut folder_path = self.path.clone();
folder_path.push(self.platform.folder_name(build_info));
folder_path
}
fn installation(&self, build_info: BuildInfo) -> BrowserFetcherInstallation {
let folder_path = self.folder_path(&build_info);
let executable_path = self
.kind
.executable(self.platform, &build_info, &folder_path);
BrowserFetcherInstallation {
folder_path,
executable_path,
build_info,
}
}
}