mirror of
https://github.com/herdrdev/herdr.git
synced 2026-09-24 16:01:13 +00:00
149 lines
4.4 KiB
Rust
149 lines
4.4 KiB
Rust
#[cfg(unix)]
|
|
mod unix;
|
|
|
|
#[cfg(unix)]
|
|
pub(crate) use unix::*;
|
|
|
|
#[cfg(windows)]
|
|
pub(crate) const REATTACH_COMMAND_ENV_VAR: &str = "HERDR_REATTACH_COMMAND";
|
|
#[cfg(windows)]
|
|
pub(crate) const REMOTE_KEYBINDINGS_ENV_VAR: &str = "HERDR_REMOTE_KEYBINDINGS";
|
|
|
|
#[cfg(windows)]
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
pub(crate) enum RemoteKeybindings {
|
|
Local,
|
|
Server,
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
impl RemoteKeybindings {
|
|
fn parse(value: &str) -> Result<Self, String> {
|
|
match value {
|
|
"local" => Ok(Self::Local),
|
|
"server" => Ok(Self::Server),
|
|
_ => Err("--remote-keybindings must be 'local' or 'server'".to_string()),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub(crate) struct RemoteLaunch {
|
|
pub(crate) target: String,
|
|
pub(crate) keybindings: RemoteKeybindings,
|
|
pub(crate) live_handoff: bool,
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
pub(crate) fn extract_remote_args(
|
|
args: &[String],
|
|
) -> Result<(Vec<String>, Option<RemoteLaunch>), String> {
|
|
let mut cleaned = Vec::with_capacity(args.len());
|
|
if let Some(program) = args.first() {
|
|
cleaned.push(program.clone());
|
|
}
|
|
|
|
let mut remote_target = None;
|
|
let mut keybindings = RemoteKeybindings::Local;
|
|
let mut keybindings_seen = false;
|
|
let mut live_handoff = false;
|
|
let mut index = 1;
|
|
while index < args.len() {
|
|
let arg = &args[index];
|
|
if arg == "--" {
|
|
cleaned.extend_from_slice(&args[index..]);
|
|
break;
|
|
}
|
|
if arg == "--handoff" {
|
|
live_handoff = true;
|
|
index += 1;
|
|
continue;
|
|
}
|
|
if arg == "--remote" {
|
|
if remote_target.is_some() {
|
|
return Err("--remote can only be specified once".to_string());
|
|
}
|
|
let Some(value) = args.get(index + 1) else {
|
|
return Err("missing value for --remote".to_string());
|
|
};
|
|
remote_target = Some(validate_remote_target(value)?.to_owned());
|
|
index += 2;
|
|
continue;
|
|
}
|
|
if let Some(value) = arg.strip_prefix("--remote=") {
|
|
if remote_target.is_some() {
|
|
return Err("--remote can only be specified once".to_string());
|
|
}
|
|
remote_target = Some(validate_remote_target(value)?.to_owned());
|
|
index += 1;
|
|
continue;
|
|
}
|
|
if arg == "--remote-keybindings" {
|
|
if keybindings_seen {
|
|
return Err("--remote-keybindings can only be specified once".to_string());
|
|
}
|
|
let Some(value) = args.get(index + 1) else {
|
|
return Err("missing value for --remote-keybindings".to_string());
|
|
};
|
|
keybindings = RemoteKeybindings::parse(value)?;
|
|
keybindings_seen = true;
|
|
index += 2;
|
|
continue;
|
|
}
|
|
if let Some(value) = arg.strip_prefix("--remote-keybindings=") {
|
|
if keybindings_seen {
|
|
return Err("--remote-keybindings can only be specified once".to_string());
|
|
}
|
|
keybindings = RemoteKeybindings::parse(value)?;
|
|
keybindings_seen = true;
|
|
index += 1;
|
|
continue;
|
|
}
|
|
|
|
cleaned.push(arg.clone());
|
|
index += 1;
|
|
}
|
|
|
|
let remote = remote_target.map(|target| RemoteLaunch {
|
|
target,
|
|
keybindings,
|
|
live_handoff,
|
|
});
|
|
if remote.is_none() && keybindings_seen {
|
|
return Err("--remote-keybindings requires --remote".to_string());
|
|
}
|
|
if remote.is_none() && live_handoff {
|
|
cleaned.push("--handoff".to_string());
|
|
}
|
|
|
|
Ok((cleaned, remote))
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
fn validate_remote_target(target: &str) -> Result<&str, String> {
|
|
if target.is_empty() {
|
|
return Err("missing value for --remote".to_string());
|
|
}
|
|
if target.starts_with('-') {
|
|
return Err("--remote target must not start with '-'".to_string());
|
|
}
|
|
Ok(target)
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
pub(crate) fn run_remote(_remote: RemoteLaunch) -> std::io::Result<()> {
|
|
debug_assert!(!crate::platform::capabilities().remote_attach);
|
|
Err(std::io::Error::other(
|
|
"remote mode is not supported on Windows yet",
|
|
))
|
|
}
|
|
|
|
#[cfg(windows)]
|
|
pub(crate) fn run_remote_client_bridge() -> std::io::Result<()> {
|
|
debug_assert!(!crate::platform::capabilities().remote_attach);
|
|
Err(std::io::Error::other(
|
|
"remote client bridge is not supported on Windows yet",
|
|
))
|
|
}
|