use std::{
fmt::Debug,
io,
path::PathBuf,
sync::{Arc, Mutex},
};
use tempfile::TempDir;
use crate::{common::compiler::CompilationResult, runtimes::CodeRuntime};
#[cfg(feature = "cpp")]
pub mod cpp_compiler;
#[cfg(feature = "python")]
pub mod python_compiler;
pub mod rust_compiler;
pub trait Compiler<R: CodeRuntime>: Send + Sync + Sized {
type Config: Send + Sync + Sized + Debug + Clone + Default + IntoArgs;
fn compile(
&self,
code: &mut impl io::Read,
config: Self::Config,
) -> CompilationResult<CompiledCode<R>>;
}
#[derive(Debug, Clone)]
pub struct CompiledCode<R: CodeRuntime> {
pub executable: Option<PathBuf>,
pub temp_dir_handle: Arc<Mutex<Option<TempDir>>>,
pub additional_data: R::AdditionalData,
pub runtime_marker: std::marker::PhantomData<R>,
}
impl<R: CodeRuntime> CompiledCode<R> {
pub fn clean_up(&mut self) -> io::Result<()> {
match self.temp_dir_handle.lock().unwrap().take() {
Some(temp_dir) => {
temp_dir.close()?;
}
None => {}
}
Ok(())
}
}
impl<R: CodeRuntime> Drop for CompiledCode<R> {
fn drop(&mut self) {
self.clean_up().unwrap();
}
}
pub trait IntoArgs {
fn into_args(self) -> Vec<String>;
}