t_rust_less_lib/clipboard/
windows.rs1use clipboard_win::formats::RawData;
2use log::error;
3
4use super::{ClipboardCommon, ClipboardResult, SelectionProvider};
5use crate::api::{ClipboardProviding, EventData, EventHub};
6use std::sync::{Arc, RwLock};
7
8pub struct Clipboard {
9 provider: Arc<RwLock<dyn SelectionProvider>>,
10 event_hub: Arc<dyn EventHub>,
11}
12
13impl Clipboard {
14 fn fill(&self) {
15 match self.provider.read() {
16 Ok(provider) => {
17 if let (Some(providing), Some(value)) = (provider.current_selection(), provider.get_selection_value()) {
18 match clipboard_win::set_clipboard_string(&value) {
19 Ok(_) => self.event_hub.send(EventData::ClipboardProviding(providing)),
20 Err(err) => error!("Write to win_clipboard failed {}", err),
21 }
22 } else {
23 self.destroy();
24 }
25 }
26 Err(err) => {
27 error!("Unable to lock provider {}", err);
28 self.destroy();
29 }
30 }
31 }
32}
33
34impl ClipboardCommon for Clipboard {
35 fn new<T>(selection_provider: T, event_hub: Arc<dyn EventHub>) -> ClipboardResult<Clipboard>
36 where
37 T: SelectionProvider + 'static,
38 {
39 let clipboard = Clipboard {
40 provider: Arc::new(RwLock::new(selection_provider)),
41 event_hub,
42 };
43 clipboard.fill();
44
45 Ok(clipboard)
46 }
47
48 fn is_open(&self) -> bool {
49 self.currently_providing().is_none()
50 }
51
52 fn currently_providing(&self) -> Option<ClipboardProviding> {
53 self.provider.read().ok()?.current_selection()
54 }
55
56 fn provide_next(&self) {
57 match self.provider.write() {
58 Ok(mut provider) => provider.next_selection(),
59 Err(err) => {
60 error!("Unable to lock provider {}", err);
61 }
62 }
63 self.fill();
64 }
65
66 fn destroy(&self) {
67 clipboard_win::set_clipboard(RawData(0), b" ").ok();
68 }
69
70 fn wait(&self) -> ClipboardResult<()> {
71 Ok(())
72 }
73}