aboutsummaryrefslogtreecommitdiff
path: root/bundle/src-tauri/src
diff options
context:
space:
mode:
Diffstat (limited to 'bundle/src-tauri/src')
-rw-r--r--bundle/src-tauri/src/compiler.rs41
-rw-r--r--bundle/src-tauri/src/main.rs9
2 files changed, 47 insertions, 3 deletions
diff --git a/bundle/src-tauri/src/compiler.rs b/bundle/src-tauri/src/compiler.rs
new file mode 100644
index 0000000..275a707
--- /dev/null
+++ b/bundle/src-tauri/src/compiler.rs
@@ -0,0 +1,41 @@
+use std::path::PathBuf;
+
+// Keep startup failures available to the UI, including an unwritable working directory.
+pub struct Compiler(pub Result<PathBuf, String>);
+
+impl Compiler {
+ pub fn load() -> Self {
+ Self(executable().map_err(|error| format!("Cannot load compiler: {error}")))
+ }
+}
+
+#[cfg(not(windows))]
+fn executable() -> std::io::Result<PathBuf> {
+ Ok(std::env::current_exe()?.with_file_name("cpsc"))
+}
+
+#[cfg(windows)]
+fn executable() -> std::io::Result<PathBuf> {
+ use std::{
+ fs::{self, File},
+ io,
+ };
+
+ let directory = std::env::current_dir()?;
+ let destination = directory.join("cpsc.exe");
+ let staged = directory.join(format!(".cpsc-{}.tmp", std::process::id()));
+ let result = (|| {
+ let mut compressed = flate2::read::GzDecoder::new(
+ &include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/binaries/cpsc.exe.gz"))[..],
+ );
+ let mut file = File::create(&staged)?;
+ io::copy(&mut compressed, &mut file)?;
+ drop(file);
+ fs::rename(&staged, &destination)?;
+ Ok(destination)
+ })();
+ if result.is_err() {
+ let _ = fs::remove_file(staged);
+ }
+ result
+}
diff --git a/bundle/src-tauri/src/main.rs b/bundle/src-tauri/src/main.rs
index 96f040c..07f25b3 100644
--- a/bundle/src-tauri/src/main.rs
+++ b/bundle/src-tauri/src/main.rs
@@ -1,6 +1,8 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
+mod compiler;
mod runner;
+use compiler::Compiler;
use runner::{OutputEvent, Runner};
use tauri::{ipc::Channel, Manager, State};
@@ -20,10 +22,9 @@ async fn run_file(
input: String,
output: Channel<OutputEvent>,
runner: State<'_, Runner>,
+ compiler: State<'_, Compiler>,
) -> Result<(), String> {
- let executable = std::env::current_exe()
- .map_err(|error| error.to_string())?
- .with_file_name(if cfg!(windows) { "cpsc.exe" } else { "cpsc" });
+ let executable = compiler.inner().0.clone()?;
let result = runner
.run(executable, path.into(), input, |stream, bytes| {
let _ = output.send(OutputEvent::Data {
@@ -47,9 +48,11 @@ async fn stop_run(runner: State<'_, Runner>) -> Result<(), String> {
}
fn main() {
+ let compiler = Compiler::load();
tauri::Builder::default()
.plugin(tauri_plugin_dialog::init())
.manage(Runner::default())
+ .manage(compiler)
.invoke_handler(tauri::generate_handler![
read_file, write_file, run_file, stop_run
])