oxdock_process/
serial_cargo_env.rs1use oxdock_fs::GuardedPath;
2use std::sync::{Mutex, MutexGuard};
3
4static ENV_LOCK: Mutex<()> = Mutex::new(());
5
6pub struct SerialCargoEnv<'a> {
14 _lock: MutexGuard<'a, ()>,
15 prev_manifest: Option<String>,
16 prev_primary: Option<String>,
17}
18
19impl<'a> SerialCargoEnv<'a> {
20 pub fn new(manifest_dir: &GuardedPath, primary: bool) -> Self {
25 let lock = ENV_LOCK.lock().expect("environment lock");
26 let prev_manifest = std::env::var("CARGO_MANIFEST_DIR").ok();
27 let prev_primary = std::env::var("CARGO_PRIMARY_PACKAGE").ok();
28 unsafe {
31 std::env::set_var("CARGO_MANIFEST_DIR", manifest_dir.as_path());
32 std::env::set_var("CARGO_PRIMARY_PACKAGE", if primary { "1" } else { "0" });
33 }
34 Self {
35 _lock: lock,
36 prev_manifest,
37 prev_primary,
38 }
39 }
40}
41
42impl Drop for SerialCargoEnv<'_> {
43 fn drop(&mut self) {
44 unsafe {
45 if let Some(prev) = &self.prev_manifest {
46 std::env::set_var("CARGO_MANIFEST_DIR", prev);
47 } else {
48 std::env::remove_var("CARGO_MANIFEST_DIR");
49 }
50
51 if let Some(prev) = &self.prev_primary {
52 std::env::set_var("CARGO_PRIMARY_PACKAGE", prev);
53 } else {
54 std::env::remove_var("CARGO_PRIMARY_PACKAGE");
55 }
56 }
57 }
58}
59
60pub fn manifest_env_guard<'a>(manifest_dir: &'a GuardedPath, primary: bool) -> SerialCargoEnv<'a> {
62 SerialCargoEnv::new(manifest_dir, primary)
63}