From 1589ee9da5fef35a13c70892b395a52ddcdac75b Mon Sep 17 00:00:00 2001 From: Corentin LIAUD Date: Wed, 27 Aug 2025 19:40:27 +0200 Subject: [PATCH] breaking(features): add mdns feature + example --- .github/workflows/python-build.yml | 2 +- .github/workflows/rust-build.yml | 6 +++--- Cargo.toml | 2 +- adb_cli/Cargo.toml | 2 +- adb_client/Cargo.toml | 18 +++++++++++++--- adb_client/README.md | 13 ++++++++++++ adb_client/src/adb_device_ext.rs | 2 +- .../src/device/adb_message_device_commands.rs | 2 +- adb_client/src/device/adb_tcp_device.rs | 2 +- adb_client/src/device/adb_usb_device.rs | 2 +- adb_client/src/device/commands/shell.rs | 2 +- adb_client/src/error.rs | 4 ++++ adb_client/src/lib.rs | 9 ++++++++ .../adb_server_device_commands.rs | 2 +- examples/mdns/Cargo.toml | 15 +++++++++++++ examples/mdns/src/main.rs | 21 +++++++++++++++++++ 16 files changed, 89 insertions(+), 15 deletions(-) create mode 100644 examples/mdns/Cargo.toml create mode 100644 examples/mdns/src/main.rs diff --git a/.github/workflows/python-build.yml b/.github/workflows/python-build.yml index 673556c..f13e6d4 100644 --- a/.github/workflows/python-build.yml +++ b/.github/workflows/python-build.yml @@ -35,4 +35,4 @@ jobs: with: files: | target/wheels/pyadb_client*.whl - target/wheels/pyadb_client*.tar.gz \ No newline at end of file + target/wheels/pyadb_client*.tar.gz diff --git a/.github/workflows/rust-build.yml b/.github/workflows/rust-build.yml index 9b1a1ff..8fcd1a2 100644 --- a/.github/workflows/rust-build.yml +++ b/.github/workflows/rust-build.yml @@ -18,6 +18,6 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] steps: - - uses: actions/checkout@v4 - - name: Build project - run: cargo build --release --all-features \ No newline at end of file + - uses: actions/checkout@v4 + - name: Build project + run: cargo build --release --all-features diff --git a/Cargo.toml b/Cargo.toml index 8f7dcd4..b7eb6db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace] -members = ["adb_cli", "adb_client", "pyadb_client"] +members = ["adb_cli", "adb_client", "examples/mdns", "pyadb_client"] resolver = "2" [workspace.package] diff --git a/adb_cli/Cargo.toml b/adb_cli/Cargo.toml index 2885bc9..02459a4 100644 --- a/adb_cli/Cargo.toml +++ b/adb_cli/Cargo.toml @@ -11,7 +11,7 @@ rust-version.workspace = true version.workspace = true [dependencies] -adb_client = { version = "^2.0.0" } +adb_client = { version = "^2.0.0", features = ["mdns"] } anyhow = { version = "1.0.94" } clap = { version = "4.5.23", features = ["derive"] } env_logger = { version = "0.11.5" } diff --git a/adb_client/Cargo.toml b/adb_client/Cargo.toml index 590f75a..3006834 100644 --- a/adb_client/Cargo.toml +++ b/adb_client/Cargo.toml @@ -10,6 +10,14 @@ repository.workspace = true rust-version.workspace = true version.workspace = true +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[features] +default = [] +mdns = ["dep:mdns-sd"] + [dependencies] base64 = { version = "0.22.1" } bincode = { version = "1.3.3" } @@ -18,9 +26,6 @@ chrono = { version = "0.4.40", default-features = false, features = ["std"] } homedir = { version = "= 0.3.4" } image = { version = "0.25.5", default-features = false } log = { version = "0.4.26" } -mdns-sd = { version = "0.13.9", default-features = false, features = [ - "logging", -] } num-bigint = { version = "0.8.4", package = "num-bigint-dig" } num-traits = { version = "0.2.19" } quick-protobuf = { version = "0.8.1" } @@ -39,6 +44,13 @@ serde_repr = { version = "0.1.19" } sha1 = { version = "0.10.6", features = ["oid"] } thiserror = { version = "2.0.7" } +######### +# MDNS dependencies +mdns-sd = { version = "0.13.9", default-features = false, features = [ + "logging", +], optional = true } +######### + [dev-dependencies] anyhow = { version = "1.0.93" } criterion = { version = "0.6.0" } # Used for benchmarks diff --git a/adb_client/README.md b/adb_client/README.md index bc8af35..d284cca 100644 --- a/adb_client/README.md +++ b/adb_client/README.md @@ -16,6 +16,19 @@ Add `adb_client` crate as a dependency by simply adding it to your `Cargo.toml`: adb_client = "*" ``` +## Crate features + +|Feature|Description|Default?| +|:-----:|:---------:|:-----:| +|`mdns`|Enables mDNS device discovery on local network.|No| + +To deactivate some features you can use the `default-features = false` option in your `Cargo.toml` file and manually specify the features you want to activate: + +```toml +[dependencies] +adb_client = { version = "*", default-features = false, features=[""] } +``` + ## Benchmarks Benchmarks run on `v2.0.6`, on a **Samsung S10 SM-G973F** device and an **Intel i7-1265U** CPU laptop diff --git a/adb_client/src/adb_device_ext.rs b/adb_client/src/adb_device_ext.rs index 9fc99a4..a342f3a 100644 --- a/adb_client/src/adb_device_ext.rs +++ b/adb_client/src/adb_device_ext.rs @@ -13,7 +13,7 @@ pub trait ADBDeviceExt { /// Starts an interactive shell session on the device. /// Input data is read from reader and write to writer. - fn shell(&mut self, reader: &mut dyn Read, writer: Box<(dyn Write + Send)>) -> Result<()>; + fn shell(&mut self, reader: &mut dyn Read, writer: Box) -> Result<()>; /// Display the stat information for a remote file fn stat(&mut self, remote_path: &str) -> Result; diff --git a/adb_client/src/device/adb_message_device_commands.rs b/adb_client/src/device/adb_message_device_commands.rs index 78b9e02..994676e 100644 --- a/adb_client/src/device/adb_message_device_commands.rs +++ b/adb_client/src/device/adb_message_device_commands.rs @@ -11,7 +11,7 @@ impl ADBDeviceExt for ADBMessageDevice { self.shell_command(command, output) } - fn shell(&mut self, reader: &mut dyn Read, writer: Box<(dyn Write + Send)>) -> Result<()> { + fn shell(&mut self, reader: &mut dyn Read, writer: Box) -> Result<()> { self.shell(reader, writer) } diff --git a/adb_client/src/device/adb_tcp_device.rs b/adb_client/src/device/adb_tcp_device.rs index 5f2e8d3..ac6b39f 100644 --- a/adb_client/src/device/adb_tcp_device.rs +++ b/adb_client/src/device/adb_tcp_device.rs @@ -75,7 +75,7 @@ impl ADBDeviceExt for ADBTcpDevice { } #[inline] - fn shell(&mut self, reader: &mut dyn Read, writer: Box<(dyn Write + Send)>) -> Result<()> { + fn shell(&mut self, reader: &mut dyn Read, writer: Box) -> Result<()> { self.inner.shell(reader, writer) } diff --git a/adb_client/src/device/adb_usb_device.rs b/adb_client/src/device/adb_usb_device.rs index 1de4376..b85db84 100644 --- a/adb_client/src/device/adb_usb_device.rs +++ b/adb_client/src/device/adb_usb_device.rs @@ -260,7 +260,7 @@ impl ADBDeviceExt for ADBUSBDevice { } #[inline] - fn shell<'a>(&mut self, reader: &mut dyn Read, writer: Box<(dyn Write + Send)>) -> Result<()> { + fn shell<'a>(&mut self, reader: &mut dyn Read, writer: Box) -> Result<()> { self.inner.shell(reader, writer) } diff --git a/adb_client/src/device/commands/shell.rs b/adb_client/src/device/commands/shell.rs index eea7097..99dc873 100644 --- a/adb_client/src/device/commands/shell.rs +++ b/adb_client/src/device/commands/shell.rs @@ -36,7 +36,7 @@ impl ADBMessageDevice { pub(crate) fn shell( &mut self, mut reader: &mut dyn Read, - mut writer: Box<(dyn Write + Send)>, + mut writer: Box, ) -> Result<()> { self.open_session(b"shell:\0")?; diff --git a/adb_client/src/error.rs b/adb_client/src/error.rs index 0164211..6243eec 100644 --- a/adb_client/src/error.rs +++ b/adb_client/src/error.rs @@ -112,9 +112,13 @@ pub enum RustADBError { #[error("upgrade error: {0}")] UpgradeError(String), /// An error occurred while getting mdns devices + #[cfg(feature = "mdns")] + #[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] #[error(transparent)] MDNSError(#[from] mdns_sd::Error), /// An error occurred while sending data to channel + #[cfg(feature = "mdns")] + #[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] #[error(transparent)] SendError(#[from] std::sync::mpsc::SendError), /// An unknown transport has been provided diff --git a/adb_client/src/lib.rs b/adb_client/src/lib.rs index 8c88387..06dfd4a 100644 --- a/adb_client/src/lib.rs +++ b/adb_client/src/lib.rs @@ -3,12 +3,19 @@ #![forbid(missing_debug_implementations)] #![forbid(missing_docs)] #![doc = include_str!("../README.md")] +// Feature `doc_cfg` is currently only available on nightly. +// It is activated when cfg `docsrs` is enabled. +// Documentation can be build locally using: +// `RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --no-deps --all-features` +#![cfg_attr(docsrs, feature(doc_cfg))] mod adb_device_ext; mod constants; mod device; mod emulator_device; mod error; +#[cfg(feature = "mdns")] +#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] mod mdns; mod models; mod server; @@ -20,6 +27,8 @@ pub use adb_device_ext::ADBDeviceExt; pub use device::{ADBTcpDevice, ADBUSBDevice, is_adb_device, search_adb_devices}; pub use emulator_device::ADBEmulatorDevice; pub use error::{Result, RustADBError}; +#[cfg(feature = "mdns")] +#[cfg_attr(docsrs, doc(cfg(feature = "mdns")))] pub use mdns::*; pub use models::{AdbStatResponse, RebootType}; pub use server::*; diff --git a/adb_client/src/server_device/adb_server_device_commands.rs b/adb_client/src/server_device/adb_server_device_commands.rs index af276ed..b6ad638 100644 --- a/adb_client/src/server_device/adb_server_device_commands.rs +++ b/adb_client/src/server_device/adb_server_device_commands.rs @@ -49,7 +49,7 @@ impl ADBDeviceExt for ADBServerDevice { fn shell( &mut self, mut reader: &mut dyn Read, - mut writer: Box<(dyn Write + Send)>, + mut writer: Box, ) -> Result<()> { let supported_features = self.host_features()?; if !supported_features.contains(&HostFeatures::ShellV2) diff --git a/examples/mdns/Cargo.toml b/examples/mdns/Cargo.toml new file mode 100644 index 0000000..5a673b5 --- /dev/null +++ b/examples/mdns/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "mdns" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +keywords.workspace = true +license.workspace = true +repository.workspace = true +version.workspace = true +rust-version.workspace = true + +[dependencies] +adb_client = { path = "../../adb_client", default-features = false, features = [ + "mdns", +] } diff --git a/examples/mdns/src/main.rs b/examples/mdns/src/main.rs new file mode 100644 index 0000000..3f3da82 --- /dev/null +++ b/examples/mdns/src/main.rs @@ -0,0 +1,21 @@ +use adb_client::{MDNSDevice, MDNSDiscoveryService}; +use std::sync::mpsc; +use std::time::Duration; + +fn main() -> Result<(), Box> { + println!("Starting mDNS device discovery..."); + + // Create a channel to receive discovered devices information + let (sender, receiver) = mpsc::channel::(); + + // Create and start the discovery service + let mut discovery = MDNSDiscoveryService::new()?; + discovery.start(sender)?; + + loop { + if let Ok(device) = receiver.recv_timeout(Duration::from_millis(100)) { + println!("Found device: {}", device.fullname); + println!(" Addresses: {:?}", device.addresses); + } + } +}