ferroui_base/input/
data_transfer.rs1use super::{DataFormat, DataTransferItem, IAsyncDataTransfer, IAsyncDataTransferItem, IDataTransfer, IDataTransferItem};
2use crate::reactive::IDisposable;
3use std::cell::RefCell;
4use std::rc::Rc;
5
6#[derive(Default)]
7struct Cache {
8 formats: Option<Rc<[DataFormat]>>,
9 items: Option<Rc<[Rc<DataTransferItem>]>>,
10 sync_items: Option<Rc<[Rc<dyn IDataTransferItem>]>>,
11 async_items: Option<Rc<[Rc<dyn IAsyncDataTransferItem>]>>,
12}
13
14pub struct DataTransfer {
21 items: RefCell<Vec<Rc<DataTransferItem>>>,
22 cache: RefCell<Cache>,
23}
24
25impl DataTransfer {
26 pub fn new() -> Rc<DataTransfer> {
28 Rc::new(DataTransfer { items: RefCell::new(Vec::new()), cache: RefCell::new(Cache::default()) })
29 }
30
31 pub fn formats(&self) -> Rc<[DataFormat]> {
34 if let Some(formats) = self.cache.borrow().formats.as_ref() {
35 return formats.clone();
36 }
37
38 let mut formats: Vec<DataFormat> = Vec::new();
39 for item in self.items().iter() {
40 for format in item.formats().iter() {
41 if !formats.contains(format) {
42 formats.push(format.clone());
43 }
44 }
45 }
46
47 let formats: Rc<[DataFormat]> = Rc::from(formats);
48 self.cache.borrow_mut().formats = Some(formats.clone());
49 formats
50 }
51
52 pub fn items(&self) -> Rc<[Rc<DataTransferItem>]> {
54 if let Some(items) = self.cache.borrow().items.as_ref() {
55 return items.clone();
56 }
57
58 let items: Rc<[Rc<DataTransferItem>]> = Rc::from(self.items.borrow().as_slice());
59 self.cache.borrow_mut().items = Some(items.clone());
60 items
61 }
62
63 pub fn add(&self, item: Rc<DataTransferItem>) {
65 let old = std::mem::take(&mut *self.cache.borrow_mut());
66 drop(old);
67 self.items.borrow_mut().push(item);
68 }
69}
70
71impl IDisposable for DataTransfer {
72 fn dispose(&self) {}
73}
74
75impl IDataTransfer for DataTransfer {
76 fn formats(&self) -> Rc<[DataFormat]> {
77 DataTransfer::formats(self)
78 }
79
80 fn items(&self) -> Rc<[Rc<dyn IDataTransferItem>]> {
81 if let Some(items) = self.cache.borrow().sync_items.as_ref() {
82 return items.clone();
83 }
84
85 let items: Rc<[Rc<dyn IDataTransferItem>]> =
86 self.items.borrow().iter().map(|item| item.clone() as Rc<dyn IDataTransferItem>).collect();
87 self.cache.borrow_mut().sync_items = Some(items.clone());
88 items
89 }
90
91 fn as_async_data_transfer(self: Rc<Self>) -> Option<Rc<dyn IAsyncDataTransfer>> {
92 Some(self)
93 }
94}
95
96impl IAsyncDataTransfer for DataTransfer {
97 fn formats(&self) -> Rc<[DataFormat]> {
98 DataTransfer::formats(self)
99 }
100
101 fn items(&self) -> Rc<[Rc<dyn IAsyncDataTransferItem>]> {
102 if let Some(items) = self.cache.borrow().async_items.as_ref() {
103 return items.clone();
104 }
105
106 let items: Rc<[Rc<dyn IAsyncDataTransferItem>]> =
107 self.items.borrow().iter().map(|item| item.clone() as Rc<dyn IAsyncDataTransferItem>).collect();
108 self.cache.borrow_mut().async_items = Some(items.clone());
109 items
110 }
111
112 fn as_data_transfer(self: Rc<Self>) -> Option<Rc<dyn IDataTransfer>> {
113 Some(self)
114 }
115}