t_rust_less_lib/clipboard/
windows.rs

1use 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}