diff --git a/idevice/src/lib.rs b/idevice/src/lib.rs index 58fe5d2..df59f00 100644 --- a/idevice/src/lib.rs +++ b/idevice/src/lib.rs @@ -12,6 +12,7 @@ pub mod lockdownd; #[cfg(feature = "mounter")] pub mod mounter; pub mod pairing_file; +pub mod provider; #[cfg(feature = "usbmuxd")] pub mod usbmuxd; #[cfg(feature = "xpc")] diff --git a/idevice/src/provider.rs b/idevice/src/provider.rs new file mode 100644 index 0000000..d617f10 --- /dev/null +++ b/idevice/src/provider.rs @@ -0,0 +1,54 @@ +// Jackson Coxson + +use std::net::{IpAddr, SocketAddr}; + +use tokio::net::TcpStream; + +use crate::{usbmuxd::UsbmuxdAddr, Idevice, IdeviceError}; + +pub trait IdeviceProvider { + // https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html#is-it-okay-to-use-async-fn-in-traits-what-are-the-limitations + fn connect( + &self, + port: u16, + ) -> impl std::future::Future> + Send; + fn label(&self) -> &str; +} + +pub struct TcpProvider { + addr: IpAddr, + label: String, +} + +impl IdeviceProvider for TcpProvider { + async fn connect(&self, port: u16) -> Result { + let socket_addr = SocketAddr::new(self.addr, port); + let stream = TcpStream::connect(socket_addr).await?; + Ok(Idevice::new(Box::new(stream), self.label.to_owned())) + } + fn label(&self) -> &str { + self.label.as_str() + } +} + +#[cfg(feature = "usbmuxd")] +pub struct UsbmuxdProvider { + addr: UsbmuxdAddr, + tag: u32, + device_id: u32, + label: String, +} + +#[cfg(feature = "usbmuxd")] +impl IdeviceProvider for UsbmuxdProvider { + async fn connect(&self, port: u16) -> Result { + let usbmuxd = self.addr.connect(self.tag).await?; + usbmuxd + .connect_to_device(self.device_id, port, &self.label) + .await + } + + fn label(&self) -> &str { + self.label.as_str() + } +}