59 lines
2.0 KiB
Rust
59 lines
2.0 KiB
Rust
//! 把 UTF-8 文本读写适配到当前平台的系统剪贴板命令。
|
|
//! 外部命令失败作为普通错误交给调用方处理;这里不解析或执行剪贴板中的程序文本。
|
|
//!
|
|
//! Clipboard text is always UTF-8, including Finder/LaunchServices launches without LANG.
|
|
use anyhow::{Result, bail};
|
|
#[cfg(target_os = "macos")]
|
|
/// 运行选定平台的剪贴板命令并检查其退出状态。
|
|
fn command(program: &str) -> std::process::Command {
|
|
let mut cmd = std::process::Command::new(program);
|
|
cmd.env("LC_ALL", "en_US.UTF-8")
|
|
.env("LC_CTYPE", "en_US.UTF-8")
|
|
.env("LANG", "en_US.UTF-8");
|
|
cmd
|
|
}
|
|
/// 取得系统剪贴板的 UTF-8 文本,失败作为可显示错误返回。
|
|
pub fn read() -> Result<String> {
|
|
#[cfg(target_os = "macos")]
|
|
{
|
|
let output = command("/usr/bin/pbpaste")
|
|
.arg("-Prefer")
|
|
.arg("txt")
|
|
.output()?;
|
|
if !output.status.success() {
|
|
bail!("system clipboard read failed");
|
|
}
|
|
// Never silently replace invalid bytes in the user's source.
|
|
Ok(String::from_utf8(output.stdout)?)
|
|
}
|
|
#[cfg(not(target_os = "macos"))]
|
|
{
|
|
bail!("system clipboard adapter is not available on this platform")
|
|
}
|
|
}
|
|
/// 将提供的文本交给系统剪贴板命令,不执行文本内容。
|
|
pub fn write(value: &str) -> Result<()> {
|
|
#[cfg(target_os = "macos")]
|
|
{
|
|
use std::io::Write;
|
|
let mut child = command("/usr/bin/pbcopy")
|
|
.stdin(std::process::Stdio::piped())
|
|
.spawn()?;
|
|
let mut stdin = child
|
|
.stdin
|
|
.take()
|
|
.ok_or_else(|| anyhow::anyhow!("clipboard stdin is unavailable"))?;
|
|
stdin.write_all(value.as_bytes())?;
|
|
drop(stdin);
|
|
if !child.wait()?.success() {
|
|
bail!("system clipboard write failed");
|
|
}
|
|
Ok(())
|
|
}
|
|
#[cfg(not(target_os = "macos"))]
|
|
{
|
|
let _ = value;
|
|
bail!("system clipboard adapter is not available on this platform")
|
|
}
|
|
}
|