ferroui_base/input/platform/
clipboard_extensions.rs1use super::{ClipboardError, IClipboard};
2use crate::input::{
3 AsyncDataTransferExtensions, DataFormat, DataFormatOf, DataTransfer, DataTransferItem, IAsyncDataTransfer,
4 LocalBoxFuture,
5};
6use crate::media::imaging::Bitmap;
7use crate::platform::storage::IStorageItem;
8use std::rc::Rc;
9
10struct Using(Rc<dyn IAsyncDataTransfer>);
13
14impl Drop for Using {
15 fn drop(&mut self) {
16 self.0.dispose();
17 }
18}
19
20pub trait ClipboardExtensions: IClipboard {
26 fn get_data_formats_async(&self) -> LocalBoxFuture<Result<Rc<[DataFormat]>, ClipboardError>> {
29 let data = self.try_get_data_async();
30
31 Box::pin(async move {
32 match data.await? {
33 Some(data_transfer) => {
34 let data_transfer = Using(data_transfer);
35 data_transfer.0.try_formats()
36 }
37 None => Ok(Rc::from(Vec::new())),
38 }
39 })
40 }
41
42 fn try_get_value_async<T: Clone + 'static>(
48 &self,
49 format: &DataFormatOf<T>,
50 ) -> LocalBoxFuture<Result<Option<T>, ClipboardError>> {
51 let data = self.try_get_data_async();
52 let format = format.clone();
53
54 Box::pin(async move {
55 let Some(data_transfer) = data.await? else {
56 return Ok(None);
57 };
58 let data_transfer = Using(data_transfer);
59 let result = data_transfer.0.try_get_value_async(&format).await;
60 result
61 })
62 }
63
64 fn try_get_values_async<T: Clone + 'static>(
67 &self,
68 format: &DataFormatOf<T>,
69 ) -> LocalBoxFuture<Result<Option<Vec<T>>, ClipboardError>> {
70 let data = self.try_get_data_async();
71 let format = format.clone();
72
73 Box::pin(async move {
74 let Some(data_transfer) = data.await? else {
75 return Ok(None);
76 };
77 let data_transfer = Using(data_transfer);
78 let result = data_transfer.0.try_get_values_async(&format).await;
79 result
80 })
81 }
82
83 fn set_value_async<T: 'static>(
91 &self,
92 format: &DataFormatOf<T>,
93 value: Option<T>,
94 ) -> LocalBoxFuture<Result<(), ClipboardError>> {
95 let Some(value) = value else {
96 return self.clear_async();
97 };
98
99 let data_transfer = DataTransfer::new();
100 data_transfer.add(DataTransferItem::create(format, Some(value)));
101 self.set_data_async(Some(data_transfer))
102 }
103
104 fn set_values_async<T: 'static>(
112 &self,
113 format: &DataFormatOf<T>,
114 values: Option<impl IntoIterator<Item = T>>,
115 ) -> LocalBoxFuture<Result<(), ClipboardError>>
116 where
117 Self: Sized,
118 {
119 let Some(values) = values else {
120 return self.clear_async();
121 };
122
123 let data_transfer = DataTransfer::new();
124
125 for value in values {
126 data_transfer.add(DataTransferItem::create(format, Some(value)));
127 }
128
129 if data_transfer.items().is_empty() {
130 self.clear_async()
131 } else {
132 self.set_data_async(Some(data_transfer))
133 }
134 }
135
136 fn try_get_text_async(&self) -> LocalBoxFuture<Result<Option<String>, ClipboardError>> {
138 self.try_get_value_async(&DataFormat::text())
139 }
140
141 fn try_get_file_async(&self) -> LocalBoxFuture<Result<Option<Rc<dyn IStorageItem>>, ClipboardError>> {
143 self.try_get_value_async(&DataFormat::file())
144 }
145
146 fn try_get_files_async(&self) -> LocalBoxFuture<Result<Option<Vec<Rc<dyn IStorageItem>>>, ClipboardError>> {
148 self.try_get_values_async(&DataFormat::file())
149 }
150
151 fn try_get_bitmap_async(&self) -> LocalBoxFuture<Result<Option<Rc<Bitmap>>, ClipboardError>> {
153 self.try_get_value_async(&DataFormat::bitmap())
154 }
155
156 fn set_text_async(&self, text: Option<&str>) -> LocalBoxFuture<Result<(), ClipboardError>> {
163 self.set_value_async(&DataFormat::text(), text.map(str::to_string))
164 }
165
166 fn set_file_async(&self, file: Option<Rc<dyn IStorageItem>>) -> LocalBoxFuture<Result<(), ClipboardError>> {
173 self.set_value_async(&DataFormat::file(), file)
174 }
175
176 fn set_files_async(
183 &self,
184 files: Option<impl IntoIterator<Item = Rc<dyn IStorageItem>>>,
185 ) -> LocalBoxFuture<Result<(), ClipboardError>>
186 where
187 Self: Sized,
188 {
189 self.set_values_async(&DataFormat::file(), files)
190 }
191
192 fn set_bitmap_async(&self, bitmap: Option<Rc<Bitmap>>) -> LocalBoxFuture<Result<(), ClipboardError>> {
199 self.set_value_async(&DataFormat::bitmap(), bitmap)
200 }
201}
202
203impl<I: IClipboard + ?Sized> ClipboardExtensions for I {}