95 lines
2.6 KiB
Rust
95 lines
2.6 KiB
Rust
use std::process::Stdio;
|
|
|
|
use anyhow::Context;
|
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
|
|
|
use crate::state::State;
|
|
|
|
#[derive(Default)]
|
|
pub struct LocalCopier {}
|
|
|
|
impl LocalCopier {
|
|
pub fn new() -> Self {
|
|
Self {}
|
|
}
|
|
|
|
pub async fn copy(&self, input: &[u8]) -> anyhow::Result<()> {
|
|
// FIXME: hardcode for macos
|
|
#[cfg(target_os = "macos")]
|
|
let mut copy_process = {
|
|
tokio::process::Command::new("pbcopy")
|
|
.stdin(Stdio::piped())
|
|
.spawn()?
|
|
};
|
|
#[cfg(target_os = "linux")]
|
|
let mut copy_process = {
|
|
tokio::process::Command::new("wl-copy")
|
|
.stdin(Stdio::piped())
|
|
.spawn()?
|
|
};
|
|
#[cfg(target_os = "windows")]
|
|
let mut copy_process = {
|
|
todo!("windows not supported yet");
|
|
};
|
|
|
|
if let Some(mut stdin_handle) = copy_process.stdin.take() {
|
|
stdin_handle
|
|
.write_all(input)
|
|
.await
|
|
.context("failed to write input to copy process")?;
|
|
stdin_handle
|
|
.flush()
|
|
.await
|
|
.context("failed to flush to program")?;
|
|
}
|
|
|
|
let status = copy_process.wait().await?;
|
|
tracing::info!("copy process ended with status: {:?}", status);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn paste(&self) -> anyhow::Result<Vec<u8>> {
|
|
// FIXME: hardcode for macos
|
|
#[cfg(target_os = "macos")]
|
|
let paste_process = {
|
|
tokio::process::Command::new("pbpaste")
|
|
.stdin(Stdio::piped())
|
|
.spawn()?
|
|
};
|
|
#[cfg(target_os = "linux")]
|
|
let mut paste_process = {
|
|
tokio::process::Command::new("wl-paste")
|
|
.stdin(Stdio::piped())
|
|
.spawn()?
|
|
};
|
|
#[cfg(target_os = "windows")]
|
|
let mut paste_process = {
|
|
todo!("windows not supported yet");
|
|
};
|
|
|
|
let output = paste_process.wait_with_output().await?;
|
|
|
|
if !output.status.success() {
|
|
anyhow::bail!(
|
|
"output failed with: {}, {}, exit_code: {}",
|
|
std::str::from_utf8(&output.stdout).unwrap_or_default(),
|
|
std::str::from_utf8(&output.stderr).unwrap_or_default(),
|
|
output.status.code().unwrap_or_default(),
|
|
)
|
|
}
|
|
|
|
Ok(output.stdout)
|
|
}
|
|
}
|
|
|
|
pub trait LocalCopierState {
|
|
fn local_copier(&self) -> LocalCopier;
|
|
}
|
|
|
|
impl LocalCopierState for State {
|
|
fn local_copier(&self) -> LocalCopier {
|
|
LocalCopier::new()
|
|
}
|
|
}
|