ferroui_base/input/platform/
platform_async_data_transfer.rs1use super::ClipboardError;
2use crate::input::{DataFormat, IAsyncDataTransfer, IAsyncDataTransferItem};
3use crate::reactive::IDisposable;
4use std::cell::RefCell;
5use std::rc::Rc;
6
7pub trait PlatformAsyncDataTransferImpl {
10 fn provide_formats(&self) -> Result<Vec<DataFormat>, ClipboardError>;
13
14 fn provide_items(&self) -> Result<Vec<Rc<dyn IAsyncDataTransferItem>>, ClipboardError>;
17
18 fn dispose(&self, owner: &PlatformAsyncDataTransfer);
21}
22
23pub struct PlatformAsyncDataTransfer {
26 formats: RefCell<Option<Rc<[DataFormat]>>>,
27 items: RefCell<Option<Rc<[Rc<dyn IAsyncDataTransferItem>]>>>,
28 platform_impl: Box<dyn PlatformAsyncDataTransferImpl>,
29}
30
31impl PlatformAsyncDataTransfer {
32 pub fn new(platform_impl: impl PlatformAsyncDataTransferImpl + 'static) -> Rc<PlatformAsyncDataTransfer> {
34 Rc::new(PlatformAsyncDataTransfer {
35 formats: RefCell::new(None),
36 items: RefCell::new(None),
37 platform_impl: Box::new(platform_impl),
38 })
39 }
40
41 #[track_caller]
48 pub fn formats(&self) -> Rc<[DataFormat]> {
49 match self.try_formats() {
50 Ok(formats) => formats,
51 Err(error) => panic!("{error}"),
52 }
53 }
54
55 pub fn try_formats(&self) -> Result<Rc<[DataFormat]>, ClipboardError> {
58 if let Some(formats) = self.formats.borrow().as_ref() {
59 return Ok(formats.clone());
60 }
61
62 let formats: Rc<[DataFormat]> = Rc::from(self.platform_impl.provide_formats()?);
63 *self.formats.borrow_mut() = Some(formats.clone());
64 Ok(formats)
65 }
66
67 pub fn are_formats_initialized(&self) -> bool {
69 self.formats.borrow().is_some()
70 }
71
72 #[track_caller]
79 pub fn items(&self) -> Rc<[Rc<dyn IAsyncDataTransferItem>]> {
80 match self.try_items() {
81 Ok(items) => items,
82 Err(error) => panic!("{error}"),
83 }
84 }
85
86 pub fn try_items(&self) -> Result<Rc<[Rc<dyn IAsyncDataTransferItem>]>, ClipboardError> {
89 if let Some(items) = self.items.borrow().as_ref() {
90 return Ok(items.clone());
91 }
92
93 let items: Rc<[Rc<dyn IAsyncDataTransferItem>]> = Rc::from(self.platform_impl.provide_items()?);
94 *self.items.borrow_mut() = Some(items.clone());
95 Ok(items)
96 }
97
98 pub fn are_items_initialized(&self) -> bool {
100 self.items.borrow().is_some()
101 }
102}
103
104impl IDisposable for PlatformAsyncDataTransfer {
105 fn dispose(&self) {
106 self.platform_impl.dispose(self)
107 }
108}
109
110impl IAsyncDataTransfer for PlatformAsyncDataTransfer {
111 fn formats(&self) -> Rc<[DataFormat]> {
112 PlatformAsyncDataTransfer::formats(self)
113 }
114
115 fn items(&self) -> Rc<[Rc<dyn IAsyncDataTransferItem>]> {
116 PlatformAsyncDataTransfer::items(self)
117 }
118
119 fn try_formats(&self) -> Result<Rc<[DataFormat]>, ClipboardError> {
120 PlatformAsyncDataTransfer::try_formats(self)
121 }
122
123 fn try_items(&self) -> Result<Rc<[Rc<dyn IAsyncDataTransferItem>]>, ClipboardError> {
124 PlatformAsyncDataTransfer::try_items(self)
125 }
126}