use std::sync::Arc; use async_trait::async_trait; use dagger_sdk::Container; use crate::{dagger_middleware::DaggerMiddleware, leptos_service::LeptosService}; use super::{ architecture::{Architecture, Os}, RustService, }; pub struct CargoBInstall { arch: Architecture, os: Os, version: String, crates: Vec, } impl CargoBInstall { pub fn new( arch: Architecture, os: Os, version: impl Into, crates: impl Into>, ) -> Self { Self { arch, os, version: version.into(), crates: crates.into(), } } fn get_arch(&self) -> String { match self.arch { Architecture::Amd64 => "x86_64", Architecture::Arm64 => "armv7", } .into() } fn get_os(&self) -> String { match self.os { Os::Linux => "linux", Os::MacOS => "darwin", } .into() } pub fn get_download_url(&self) -> String { format!("https://github.com/cargo-bins/cargo-binstall/releases/{}/download/cargo-binstall-{}-unknown-{}-musl.tgz", self.version, self.get_arch(), self.get_os()) } pub fn get_archive(&self) -> String { format!( "cargo-binstall-{}-unknown-{}-musl.tgz", self.get_arch(), self.get_os() ) } } #[async_trait] impl DaggerMiddleware for CargoBInstall { async fn handle(&self, container: Container) -> eyre::Result { let c = container .with_exec(vec!["wget", &self.get_download_url()]) .with_exec(vec!["tar", "-xvf", &self.get_archive()]) .with_exec( "mv cargo-binstall /usr/local/cargo/bin" .split_whitespace() .collect(), ); let c = self.crates.iter().cloned().fold(c, |acc, item| { acc.with_exec(vec!["cargo", "binstall", &item, "-y"]) }); Ok(c) } } pub trait CargoBInstallExt { fn with_cargo_binstall( &mut self, version: impl Into, crates: impl IntoIterator>, ) -> &mut Self { self } } impl CargoBInstallExt for RustService { fn with_cargo_binstall( &mut self, version: impl Into, crates: impl IntoIterator>, ) -> &mut Self { let crates: Vec = crates.into_iter().map(|s| s.into()).collect(); self.with_stage(super::RustServiceStage::BeforeDeps(Arc::new( CargoBInstall::new(self.get_arch(), self.get_os(), version, crates), ))) } } impl CargoBInstallExt for LeptosService { fn with_cargo_binstall( &mut self, version: impl Into, crates: impl IntoIterator>, ) -> &mut Self { let crates: Vec = crates.into_iter().map(|s| s.into()).collect(); self.with_stage(super::RustServiceStage::BeforeDeps(Arc::new( CargoBInstall::new(self.get_arch(), self.get_os(), version, crates), ))) } }