1use std::path::Path;
2use std::path::PathBuf;
3
4use muxr_core::SessionName;
5use rootcause::prelude::ResultExt;
6use rootcause::report;
7
8const SERVER_EXECUTABLE: &str = "muxr-server";
9
10pub fn run(session: &SessionName, external_layout: Option<PathBuf>) -> rootcause::Result<()> {
11 let current_exe = std::env::current_exe().context("failed to resolve muxr executable")?;
12 let server_executable = server_executable_next_to(¤t_exe)?;
13 let external_layout = match external_layout {
14 Some(path) if path.is_relative() => Some(
15 std::env::current_dir()
16 .context("failed to resolve muxr cwd")?
17 .join(path),
18 ),
19 Some(path) => Some(path),
20 None => None,
21 };
22 muxr_client::start(session, &server_executable, external_layout.as_deref())?;
23 Ok(())
24}
25
26pub(super) fn server_executable_next_to(current_exe: &Path) -> rootcause::Result<PathBuf> {
27 let Some(parent) = current_exe.parent().filter(|parent| !parent.as_os_str().is_empty()) else {
28 return Err(
29 report!("muxr executable has no parent dir").attach(format!("executable={}", current_exe.display()))
30 );
31 };
32 Ok(parent.join(SERVER_EXECUTABLE))
35}
36
37#[cfg(test)]
38mod tests {
39 use test_that::prelude::*;
40
41 use super::*;
42
43 #[test]
44 fn test_server_executable_next_to_returns_sibling_without_checking_existence() -> rootcause::Result<()> {
45 let tempdir = tempfile::tempdir()?;
46 let muxr = tempdir.path().join("muxr");
47 let runner = tempdir.path().join(SERVER_EXECUTABLE);
48
49 assert_that!(server_executable_next_to(&muxr)?, eq(runner));
50 Ok(())
51 }
52}