mirror of
https://github.com/jkcoxson/idevice.git
synced 2026-03-02 14:36:16 +01:00
Pin and box IdeviceProvider because async traits are unstable
This commit is contained in:
@@ -70,7 +70,7 @@ impl IdeviceService for CoreDeviceProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn connect(
|
async fn connect(
|
||||||
provider: &impl crate::provider::IdeviceProvider,
|
provider: &dyn crate::provider::IdeviceProvider,
|
||||||
) -> Result<Self, IdeviceError> {
|
) -> Result<Self, IdeviceError> {
|
||||||
let mut lockdown = LockdowndClient::connect(provider).await?;
|
let mut lockdown = LockdowndClient::connect(provider).await?;
|
||||||
let (port, ssl) = lockdown.start_service(Self::service_name()).await?;
|
let (port, ssl) = lockdown.start_service(Self::service_name()).await?;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ impl IdeviceService for HeartbeatClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn connect(
|
async fn connect(
|
||||||
provider: &impl crate::provider::IdeviceProvider,
|
provider: &dyn crate::provider::IdeviceProvider,
|
||||||
) -> Result<Self, IdeviceError> {
|
) -> Result<Self, IdeviceError> {
|
||||||
let mut lockdown = LockdowndClient::connect(provider).await?;
|
let mut lockdown = LockdowndClient::connect(provider).await?;
|
||||||
let (port, ssl) = lockdown.start_service(Self::service_name()).await?;
|
let (port, ssl) = lockdown.start_service(Self::service_name()).await?;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ impl IdeviceService for InstallationProxyClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn connect(
|
async fn connect(
|
||||||
provider: &impl crate::provider::IdeviceProvider,
|
provider: &dyn crate::provider::IdeviceProvider,
|
||||||
) -> Result<Self, IdeviceError> {
|
) -> Result<Self, IdeviceError> {
|
||||||
let mut lockdown = LockdowndClient::connect(provider).await?;
|
let mut lockdown = LockdowndClient::connect(provider).await?;
|
||||||
let (port, ssl) = lockdown.start_service(Self::service_name()).await?;
|
let (port, ssl) = lockdown.start_service(Self::service_name()).await?;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ impl<T: AsyncRead + AsyncWrite + Unpin + Send + Sync + std::fmt::Debug> ReadWrit
|
|||||||
pub trait IdeviceService: Sized {
|
pub trait IdeviceService: Sized {
|
||||||
fn service_name() -> &'static str;
|
fn service_name() -> &'static str;
|
||||||
fn connect(
|
fn connect(
|
||||||
provider: &impl IdeviceProvider,
|
provider: &dyn IdeviceProvider,
|
||||||
) -> impl std::future::Future<Output = Result<Self, IdeviceError>> + Send;
|
) -> impl std::future::Future<Output = Result<Self, IdeviceError>> + Send;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,6 +202,9 @@ pub enum IdeviceError {
|
|||||||
#[error("JSON serialization failed")]
|
#[error("JSON serialization failed")]
|
||||||
Json(#[from] serde_json::Error),
|
Json(#[from] serde_json::Error),
|
||||||
|
|
||||||
|
#[error("device not found")]
|
||||||
|
DeviceNotFound,
|
||||||
|
|
||||||
#[error("unknown error `{0}` returned from device")]
|
#[error("unknown error `{0}` returned from device")]
|
||||||
UnknownErrorType(String),
|
UnknownErrorType(String),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ impl IdeviceService for LockdowndClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn connect(
|
async fn connect(
|
||||||
provider: &impl crate::provider::IdeviceProvider,
|
provider: &dyn crate::provider::IdeviceProvider,
|
||||||
) -> Result<Self, IdeviceError> {
|
) -> Result<Self, IdeviceError> {
|
||||||
let idevice = provider.connect(Self::LOCKDOWND_PORT).await?;
|
let idevice = provider.connect(Self::LOCKDOWND_PORT).await?;
|
||||||
Ok(Self { idevice })
|
Ok(Self::new(idevice))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ impl IdeviceService for ImageMounter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn connect(
|
async fn connect(
|
||||||
provider: &impl crate::provider::IdeviceProvider,
|
provider: &dyn crate::provider::IdeviceProvider,
|
||||||
) -> Result<Self, IdeviceError> {
|
) -> Result<Self, IdeviceError> {
|
||||||
let mut lockdown = LockdowndClient::connect(provider).await?;
|
let mut lockdown = LockdowndClient::connect(provider).await?;
|
||||||
let (port, ssl) = lockdown.start_service(Self::service_name()).await?;
|
let (port, ssl) = lockdown.start_service(Self::service_name()).await?;
|
||||||
|
|||||||
@@ -1,70 +1,107 @@
|
|||||||
// Jackson Coxson
|
// Jackson Coxson
|
||||||
|
|
||||||
use std::net::{IpAddr, SocketAddr};
|
use std::{
|
||||||
|
future::Future,
|
||||||
|
net::{IpAddr, SocketAddr},
|
||||||
|
pin::Pin,
|
||||||
|
};
|
||||||
|
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
|
|
||||||
use crate::{pairing_file::PairingFile, usbmuxd::UsbmuxdAddr, Idevice, IdeviceError};
|
use crate::{pairing_file::PairingFile, Idevice, IdeviceError};
|
||||||
|
|
||||||
|
#[cfg(feature = "usbmuxd")]
|
||||||
|
use crate::usbmuxd::UsbmuxdAddr;
|
||||||
|
|
||||||
|
/// A provider for connecting to the iOS device
|
||||||
|
/// This is an ugly trait until async traits are stabilized
|
||||||
pub trait IdeviceProvider: Unpin + Send + Sync + std::fmt::Debug {
|
pub trait IdeviceProvider: Unpin + Send + Sync + std::fmt::Debug {
|
||||||
// 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(
|
fn connect(
|
||||||
&self,
|
&self,
|
||||||
port: u16,
|
port: u16,
|
||||||
) -> impl std::future::Future<Output = Result<Idevice, IdeviceError>> + Send;
|
) -> Pin<Box<dyn Future<Output = Result<Idevice, IdeviceError>> + Send>>;
|
||||||
|
|
||||||
fn label(&self) -> &str;
|
fn label(&self) -> &str;
|
||||||
|
|
||||||
fn get_pairing_file(
|
fn get_pairing_file(
|
||||||
&self,
|
&self,
|
||||||
) -> impl std::future::Future<Output = Result<PairingFile, IdeviceError>> + Send;
|
) -> Pin<Box<dyn Future<Output = Result<PairingFile, IdeviceError>> + Send>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct TcpProvider {
|
pub struct TcpProvider {
|
||||||
addr: IpAddr,
|
pub addr: IpAddr,
|
||||||
pairing_file: PairingFile,
|
pub pairing_file: PairingFile,
|
||||||
label: String,
|
pub label: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IdeviceProvider for TcpProvider {
|
impl IdeviceProvider for TcpProvider {
|
||||||
async fn connect(&self, port: u16) -> Result<Idevice, IdeviceError> {
|
fn connect(
|
||||||
let socket_addr = SocketAddr::new(self.addr, port);
|
&self,
|
||||||
let stream = TcpStream::connect(socket_addr).await?;
|
port: u16,
|
||||||
Ok(Idevice::new(Box::new(stream), self.label.to_owned()))
|
) -> Pin<Box<dyn Future<Output = Result<Idevice, IdeviceError>> + Send>> {
|
||||||
}
|
let addr = self.addr;
|
||||||
fn label(&self) -> &str {
|
let label = self.label.clone();
|
||||||
self.label.as_str()
|
Box::pin(async move {
|
||||||
|
let socket_addr = SocketAddr::new(addr, port);
|
||||||
|
let stream = TcpStream::connect(socket_addr).await?;
|
||||||
|
Ok(Idevice::new(Box::new(stream), label))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_pairing_file(&self) -> Result<PairingFile, IdeviceError> {
|
fn label(&self) -> &str {
|
||||||
Ok(self.pairing_file.clone())
|
&self.label
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_pairing_file(
|
||||||
|
&self,
|
||||||
|
) -> Pin<Box<dyn Future<Output = Result<PairingFile, IdeviceError>> + Send>> {
|
||||||
|
let pairing_file = self.pairing_file.clone();
|
||||||
|
Box::pin(async move { Ok(pairing_file) })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usbmuxd")]
|
#[cfg(feature = "usbmuxd")]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct UsbmuxdProvider {
|
pub struct UsbmuxdProvider {
|
||||||
addr: UsbmuxdAddr,
|
pub addr: UsbmuxdAddr,
|
||||||
tag: u32,
|
pub tag: u32,
|
||||||
udid: String,
|
pub udid: String,
|
||||||
device_id: u32,
|
pub device_id: u32,
|
||||||
label: String,
|
pub label: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "usbmuxd")]
|
#[cfg(feature = "usbmuxd")]
|
||||||
impl IdeviceProvider for UsbmuxdProvider {
|
impl IdeviceProvider for UsbmuxdProvider {
|
||||||
async fn connect(&self, port: u16) -> Result<Idevice, IdeviceError> {
|
fn connect(
|
||||||
let usbmuxd = self.addr.connect(self.tag).await?;
|
&self,
|
||||||
usbmuxd
|
port: u16,
|
||||||
.connect_to_device(self.device_id, port, &self.label)
|
) -> Pin<Box<dyn Future<Output = Result<Idevice, IdeviceError>> + Send>> {
|
||||||
.await
|
let addr = self.addr.clone();
|
||||||
|
let tag = self.tag;
|
||||||
|
let device_id = self.device_id;
|
||||||
|
let label = self.label.clone();
|
||||||
|
|
||||||
|
Box::pin(async move {
|
||||||
|
let usbmuxd = addr.connect(tag).await?;
|
||||||
|
usbmuxd.connect_to_device(device_id, port, &label).await
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn label(&self) -> &str {
|
fn label(&self) -> &str {
|
||||||
self.label.as_str()
|
&self.label
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_pairing_file(&self) -> Result<PairingFile, IdeviceError> {
|
fn get_pairing_file(
|
||||||
let mut usbmuxd = self.addr.connect(self.tag).await?;
|
&self,
|
||||||
usbmuxd.get_pair_record(&self.udid).await
|
) -> Pin<Box<dyn Future<Output = Result<PairingFile, IdeviceError>> + Send>> {
|
||||||
|
let addr = self.addr.clone();
|
||||||
|
let tag = self.tag;
|
||||||
|
let udid = self.udid.clone();
|
||||||
|
|
||||||
|
Box::pin(async move {
|
||||||
|
let mut usbmuxd = addr.connect(tag).await?;
|
||||||
|
usbmuxd.get_pair_record(&udid).await
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user