use super::ClipboardError;
use crate::input::{DataFormat, IAsyncDataTransfer, IAsyncDataTransferItem};
use crate::reactive::IDisposable;
use std::cell::RefCell;
use std::rc::Rc;
pub trait PlatformAsyncDataTransferImpl {
fn provide_formats(&self) -> Result<Vec<DataFormat>, ClipboardError>;
fn provide_items(&self) -> Result<Vec<Rc<dyn IAsyncDataTransferItem>>, ClipboardError>;
fn dispose(&self, owner: &PlatformAsyncDataTransfer);
}
pub struct PlatformAsyncDataTransfer {
formats: RefCell<Option<Rc<[DataFormat]>>>,
items: RefCell<Option<Rc<[Rc<dyn IAsyncDataTransferItem>]>>>,
platform_impl: Box<dyn PlatformAsyncDataTransferImpl>,
}
impl PlatformAsyncDataTransfer {
pub fn new(platform_impl: impl PlatformAsyncDataTransferImpl + 'static) -> Rc<PlatformAsyncDataTransfer> {
Rc::new(PlatformAsyncDataTransfer {
formats: RefCell::new(None),
items: RefCell::new(None),
platform_impl: Box::new(platform_impl),
})
}
#[track_caller]
pub fn formats(&self) -> Rc<[DataFormat]> {
match self.try_formats() {
Ok(formats) => formats,
Err(error) => panic!("{error}"),
}
}
pub fn try_formats(&self) -> Result<Rc<[DataFormat]>, ClipboardError> {
if let Some(formats) = self.formats.borrow().as_ref() {
return Ok(formats.clone());
}
let formats: Rc<[DataFormat]> = Rc::from(self.platform_impl.provide_formats()?);
*self.formats.borrow_mut() = Some(formats.clone());
Ok(formats)
}
pub fn are_formats_initialized(&self) -> bool {
self.formats.borrow().is_some()
}
#[track_caller]
pub fn items(&self) -> Rc<[Rc<dyn IAsyncDataTransferItem>]> {
match self.try_items() {
Ok(items) => items,
Err(error) => panic!("{error}"),
}
}
pub fn try_items(&self) -> Result<Rc<[Rc<dyn IAsyncDataTransferItem>]>, ClipboardError> {
if let Some(items) = self.items.borrow().as_ref() {
return Ok(items.clone());
}
let items: Rc<[Rc<dyn IAsyncDataTransferItem>]> = Rc::from(self.platform_impl.provide_items()?);
*self.items.borrow_mut() = Some(items.clone());
Ok(items)
}
pub fn are_items_initialized(&self) -> bool {
self.items.borrow().is_some()
}
}
impl IDisposable for PlatformAsyncDataTransfer {
fn dispose(&self) {
self.platform_impl.dispose(self)
}
}
impl IAsyncDataTransfer for PlatformAsyncDataTransfer {
fn formats(&self) -> Rc<[DataFormat]> {
PlatformAsyncDataTransfer::formats(self)
}
fn items(&self) -> Rc<[Rc<dyn IAsyncDataTransferItem>]> {
PlatformAsyncDataTransfer::items(self)
}
fn try_formats(&self) -> Result<Rc<[DataFormat]>, ClipboardError> {
PlatformAsyncDataTransfer::try_formats(self)
}
fn try_items(&self) -> Result<Rc<[Rc<dyn IAsyncDataTransferItem>]>, ClipboardError> {
PlatformAsyncDataTransfer::try_items(self)
}
}