Implement clipboard and QR presentation
This commit is contained in:
85
crates/storage/src/presentation/platform.rs
Normal file
85
crates/storage/src/presentation/platform.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
//! Safe native clipboard adapter selection.
|
||||
//!
|
||||
//! Desktop adapters are supplied by `arboard`, which owns the operating-system
|
||||
//! integration. IronStorage performs no direct FFI and contains no unsafe code.
|
||||
|
||||
use super::{ClipboardBackend, ClipboardContent, ClipboardError};
|
||||
use crate::repository::SecretBytes;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
pub struct NativeClipboardBackend {
|
||||
clipboard: arboard::Clipboard,
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
impl NativeClipboardBackend {
|
||||
pub fn new() -> Result<Self, ClipboardError> {
|
||||
arboard::Clipboard::new()
|
||||
.map(|clipboard| Self { clipboard })
|
||||
.map_err(|_| ClipboardError::Unavailable)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "macos", target_os = "windows"))]
|
||||
impl ClipboardBackend for NativeClipboardBackend {
|
||||
fn read(&mut self) -> Result<ClipboardContent, ClipboardError> {
|
||||
match self.clipboard.get_text() {
|
||||
Ok(value) => Ok(ClipboardContent::text(value.into_bytes())),
|
||||
Err(arboard::Error::ContentNotAvailable) => Ok(ClipboardContent::EmptyOrNonText),
|
||||
Err(arboard::Error::ClipboardNotSupported) => Err(ClipboardError::Unavailable),
|
||||
Err(_) => Err(ClipboardError::ReadFailed),
|
||||
}
|
||||
}
|
||||
|
||||
fn write(&mut self, value: &SecretBytes) -> Result<(), ClipboardError> {
|
||||
let text = std::str::from_utf8(value.expose()).map_err(|_| ClipboardError::NonUtf8)?;
|
||||
set_text(&mut self.clipboard, text).map_err(|error| match error {
|
||||
arboard::Error::ClipboardNotSupported => ClipboardError::Unavailable,
|
||||
_ => ClipboardError::WriteFailed,
|
||||
})
|
||||
}
|
||||
|
||||
fn clear(&mut self) -> Result<(), ClipboardError> {
|
||||
self.clipboard.clear().map_err(|error| match error {
|
||||
arboard::Error::ClipboardNotSupported => ClipboardError::Unavailable,
|
||||
_ => ClipboardError::WriteFailed,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn set_text(clipboard: &mut arboard::Clipboard, text: &str) -> Result<(), arboard::Error> {
|
||||
use arboard::SetExtLinux as _;
|
||||
|
||||
clipboard.set().exclude_from_history().text(text)
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "windows"))]
|
||||
fn set_text(clipboard: &mut arboard::Clipboard, text: &str) -> Result<(), arboard::Error> {
|
||||
clipboard.set_text(text)
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
|
||||
pub struct NativeClipboardBackend;
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
|
||||
impl NativeClipboardBackend {
|
||||
pub fn new() -> Result<Self, ClipboardError> {
|
||||
Err(ClipboardError::Unavailable)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
|
||||
impl ClipboardBackend for NativeClipboardBackend {
|
||||
fn read(&mut self) -> Result<ClipboardContent, ClipboardError> {
|
||||
Err(ClipboardError::Unavailable)
|
||||
}
|
||||
|
||||
fn write(&mut self, _value: &SecretBytes) -> Result<(), ClipboardError> {
|
||||
Err(ClipboardError::Unavailable)
|
||||
}
|
||||
|
||||
fn clear(&mut self) -> Result<(), ClipboardError> {
|
||||
Err(ClipboardError::Unavailable)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user