#![cfg(windows)]
#![no_std]
#![warn(missing_docs)]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::style))]
#[cfg(feature = "std")]
extern crate std;
extern crate alloc;
mod sys;
pub mod types;
pub mod formats;
pub use formats::Format;
mod html;
pub mod raw;
#[cfg(feature = "monitor")]
pub mod monitor;
#[cfg(feature = "monitor")]
pub use monitor::Monitor;
pub(crate) mod utils;
pub use raw::{get_owner, empty, seq_num, size, is_format_avail, register_format, count_formats, EnumFormats};
pub use formats::Unicode;
pub use error_code::ErrorCode;
pub type SysResult<T> = Result<T, ErrorCode>;
pub struct Clipboard {
_dummy: ()
}
impl Clipboard {
#[inline(always)]
pub fn new() -> SysResult<Self> {
raw::open().map(|_| Self { _dummy: () })
}
#[inline(always)]
pub fn new_for(owner: types::HWND) -> SysResult<Self> {
raw::open_for(owner).map(|_| Self { _dummy: () })
}
#[inline(always)]
pub fn new_attempts(num: usize) -> SysResult<Self> {
Self::new_attempts_for(core::ptr::null_mut(), num)
}
#[inline]
pub fn new_attempts_for(owner: types::HWND, mut num: usize) -> SysResult<Self> {
loop {
match Self::new_for(owner) {
Ok(this) => break Ok(this),
Err(err) => match num {
0 => break Err(err),
_ => num -= 1,
}
}
unsafe { sys::Sleep(0) };
}
}
}
impl Drop for Clipboard {
fn drop(&mut self) {
let _ = raw::close();
}
}
pub trait Getter<Type> {
fn read_clipboard(&self, out: &mut Type) -> SysResult<usize>;
}
pub trait Setter<Type: ?Sized> {
fn write_clipboard(&self, data: &Type) -> SysResult<()>;
}
#[inline(always)]
pub fn with_clipboard<F: FnMut()>(mut cb: F) -> SysResult<()> {
let _clip = Clipboard::new()?;
cb();
Ok(())
}
#[inline(always)]
pub fn with_clipboard_attempts<F: FnMut()>(num: usize, mut cb: F) -> SysResult<()> {
let _clip = Clipboard::new_attempts(num)?;
cb();
Ok(())
}
#[inline(always)]
pub fn get<R: Default, T: Getter<R>>(format: T) -> SysResult<R> {
let mut result = R::default();
format.read_clipboard(&mut result).map(|_| result)
}
#[inline(always)]
pub fn get_clipboard<R: Default, T: Getter<R>>(format: T) -> SysResult<R> {
let _clip = Clipboard::new_attempts(10)?;
get(format)
}
#[inline(always)]
pub fn set<R, T: Setter<R>>(format: T, data: R) -> SysResult<()> {
format.write_clipboard(&data)
}
#[inline(always)]
pub fn set_clipboard<R, T: Setter<R>>(format: T, data: R) -> SysResult<()> {
let _clip = Clipboard::new_attempts(10)?;
set(format, data)
}
#[inline(always)]
pub fn get_clipboard_string() -> SysResult<alloc::string::String> {
get_clipboard(Unicode)
}
#[inline(always)]
pub fn set_clipboard_string(data: &str) -> SysResult<()> {
set_clipboard(Unicode, data)
}