use core::future::Future;
use burn_dispatch::__remote::HostSpec;
pub use burn_dispatch::__remote::{
ConnectError, Credential, CustomOpClient, Endpoint, EndpointAddr, EndpointId, InvalidRelays,
IrohHost, IrohIdentity, IrohRelays, RelayUrl,
};
use crate::{Device, DeviceIndex, Devices};
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct RemoteHost(HostSpec);
impl RemoteHost {
#[cfg(feature = "remote-websocket")]
pub fn websocket(url: &str) -> Self {
Self(HostSpec::websocket(url))
}
pub fn iroh(host: impl Into<IrohHost>) -> Self {
Self(HostSpec::iroh(host))
}
pub fn with_credential(self, credential: impl Into<Credential>) -> Self {
Self(self.0.with_credential(credential))
}
#[cfg(not(target_family = "wasm"))]
pub fn devices(&self) -> Result<Devices, ConnectError> {
Ok(self.0.devices()?.into_iter().map(Device::new).collect())
}
#[cfg(not(target_family = "wasm"))]
pub fn devices_async(
&self,
) -> impl Future<Output = Result<Devices, ConnectError>> + Send + 'static + use<> {
let devices = self.0.devices_async();
async move { Ok(devices.await?.into_iter().map(Device::new).collect()) }
}
#[cfg(target_family = "wasm")]
pub fn devices_async(
&self,
) -> impl Future<Output = Result<Devices, ConnectError>> + 'static + use<> {
let devices = self.0.devices_async();
async move { Ok(devices.await?.into_iter().map(Device::new).collect()) }
}
#[cfg(not(target_family = "wasm"))]
pub(crate) fn enumerate(&self) -> Devices {
self.devices().unwrap_or_else(|err| {
panic!("Cannot list the devices of the remote server {self:?}: {err}")
})
}
#[cfg(target_family = "wasm")]
pub(crate) fn enumerate(&self) -> Devices {
panic!(
"Listing a remote server's devices blocks, which a browser cannot do: use \
`RemoteHost::devices_async`"
)
}
}
#[must_use = "remote options do nothing until initialized"]
#[derive(Clone, Debug)]
pub struct RemoteOptions {
host: RemoteHost,
device_index: DeviceIndex,
}
impl RemoteOptions {
pub fn device_index(mut self, index: impl Into<DeviceIndex>) -> Self {
self.device_index = index.into();
self
}
#[cfg(not(target_family = "wasm"))]
pub fn init(self) -> Result<Device, ConnectError> {
Ok(Device::new(
self.host.0.connect(self.device_index.resolve())?,
))
}
#[cfg(not(target_family = "wasm"))]
pub fn init_async(
self,
) -> impl Future<Output = Result<Device, ConnectError>> + Send + 'static + use<> {
let device = self.host.0.connect_async(self.device_index.resolve());
async move { Ok(Device::new(device.await?)) }
}
#[cfg(target_family = "wasm")]
pub fn init_async(
self,
) -> impl Future<Output = Result<Device, ConnectError>> + 'static + use<> {
let device = self.host.0.connect_async(self.device_index.resolve());
async move { Ok(Device::new(device.await?)) }
}
}
impl Device {
pub fn remote_options(host: &RemoteHost) -> RemoteOptions {
RemoteOptions {
host: host.clone(),
device_index: DeviceIndex::default(),
}
}
}