feat(adb): gate built-in backend behind default feature

This commit is contained in:
Angel J 2026-06-17 22:57:11 -07:00
commit 528ef586da
No known key found for this signature in database
GPG key ID: 4CE6C8BA718B9657
6 changed files with 38 additions and 13 deletions

View file

@ -14,8 +14,12 @@ edition.workspace = true
name = "uad"
path = "src/main.rs"
[features]
default = ["builtin-adb"]
builtin-adb = ["uad-core/builtin-adb"]
[dependencies]
uad-core = { path = "../uad-core" }
uad-core = { path = "../uad-core", default-features = false }
clap.workspace = true
clap_complete = "4.4"
tokio.workspace = true

View file

@ -26,6 +26,7 @@ use filters::{ListFilter, RemovalFilter, StateFilter};
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum)]
pub enum AdbBackendArg {
/// Built-in ADB implementation (no external dependencies)
#[cfg(feature = "builtin-adb")]
Builtin,
/// Use system-installed adb binary
System,
@ -34,6 +35,7 @@ pub enum AdbBackendArg {
impl From<AdbBackendArg> for AdbBackend {
fn from(arg: AdbBackendArg) -> Self {
match arg {
#[cfg(feature = "builtin-adb")]
AdbBackendArg::Builtin => AdbBackend::Builtin,
AdbBackendArg::System => AdbBackend::System,
}
@ -46,7 +48,7 @@ impl From<AdbBackendArg> for AdbBackend {
#[command(version)]
#[command(propagate_version = true)]
pub struct Cli {
/// ADB backend to use: system (default, uses adb binary) or builtin (no dependencies)
/// ADB backend to use: system (default, uses adb binary) or builtin if enabled
#[arg(
short = 'B',
long = "backend",

View file

@ -11,11 +11,12 @@ categories = ["command-line-utilities"]
edition.workspace = true
[features]
default = []
default = ["builtin-adb"]
builtin-adb = ["dep:adb_client"]
self-update = ["dep:flate2", "dep:tar"]
[dependencies]
adb_client.workspace = true
adb_client = { workspace = true, optional = true }
serde.workspace = true
serde_json.workspace = true
log.workspace = true

View file

@ -4,7 +4,7 @@
//!
//! Following the design philosophy of most of Rust `std`,
//! `*Command` are intended to be "thin wrappers" (low-overhead abstractions)
//! around `adb_client` or the system ADB CLI,
//! around the optional `adb_client` backend or the system ADB CLI,
//! which implies:
//! - no "magic"
//! - no custom commands
@ -46,9 +46,11 @@
//! For comprehensive info about ADB,
//! [see this](https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/master/docs/)
#[cfg(feature = "builtin-adb")]
use adb_client::{ADBDeviceExt, server::ADBServer};
use serde::{Deserialize, Serialize};
use std::fmt::Write as _;
#[cfg(feature = "builtin-adb")]
use std::io::Cursor;
use std::rc::Rc;
@ -73,6 +75,7 @@ pub fn to_trimmed_utf8(v: &[u8]) -> String {
pub enum AdbBackend {
/// Built-in ADB implementation via `adb_client` crate.
/// The application can communicate with devices without needing `adb` installed.
#[cfg(feature = "builtin-adb")]
Builtin,
/// Uses the system-installed `adb` binary.
/// This is the default to preserve existing behavior.
@ -84,12 +87,18 @@ pub enum AdbBackend {
impl AdbBackend {
/// Returns all available backend variants for UI enumeration
#[cfg(feature = "builtin-adb")]
pub const ALL: [Self; 2] = [Self::Builtin, Self::System];
/// Returns all available backend variants for UI enumeration
#[cfg(not(feature = "builtin-adb"))]
pub const ALL: [Self; 1] = [Self::System];
}
impl std::fmt::Display for AdbBackend {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
#[cfg(feature = "builtin-adb")]
Self::Builtin => write!(f, "Builtin"),
Self::System => write!(f, "System (adb)"),
}
@ -189,6 +198,7 @@ impl ACommand {
/// - "device"
pub fn devices(self) -> Result<Vec<(String, String)>, String> {
match self.0.backend {
#[cfg(feature = "builtin-adb")]
AdbBackend::Builtin => Self::devices_builtin(),
AdbBackend::System => Self::devices_system(),
}
@ -212,6 +222,7 @@ impl ACommand {
/// ```
pub fn version(self) -> Result<String, String> {
match self.0.backend {
#[cfg(feature = "builtin-adb")]
AdbBackend::Builtin => Self::version_builtin(),
AdbBackend::System => Self::version_system(),
}
@ -220,6 +231,7 @@ impl ACommand {
// ========== Builtin backend implementation (adb_client) ==========
/// Get ADB server version using the builtin `adb_client`
#[cfg(feature = "builtin-adb")]
fn version_builtin() -> Result<String, String> {
let mut server = ADBServer::default();
match server.version() {
@ -232,6 +244,7 @@ impl ACommand {
}
/// List devices using the builtin `adb_client`
#[cfg(feature = "builtin-adb")]
fn devices_builtin() -> Result<Vec<(String, String)>, String> {
let mut server = ADBServer::default();
server
@ -249,6 +262,7 @@ impl ACommand {
}
/// Execute a shell command via `adb_client` (builtin backend)
#[cfg(feature = "builtin-adb")]
fn run_shell_command_builtin(&self, shell_command: &str) -> Result<String, String> {
let mut server = ADBServer::default();
@ -368,6 +382,7 @@ impl ACommand {
/// Execute a shell command using the configured backend
fn run_shell_command(&self, shell_command: &str) -> Result<String, String> {
match self.0.backend {
#[cfg(feature = "builtin-adb")]
AdbBackend::Builtin => self.run_shell_command_builtin(shell_command),
AdbBackend::System => self.run_shell_command_system(shell_command),
}
@ -610,6 +625,7 @@ mod tests {
#[test]
fn backend_display() {
#[cfg(feature = "builtin-adb")]
assert_eq!(AdbBackend::Builtin.to_string(), "Builtin");
assert_eq!(AdbBackend::System.to_string(), "System (adb)");
}

View file

@ -15,14 +15,15 @@ name = "uad-ng"
path = "src/main.rs"
[features]
default = ["wgpu", "self-update", "img"]
wgpu = [] # Iced/wgpu is default
self-update = ["flate2", "tar"]
default = ["wgpu", "self-update", "img", "builtin-adb"]
builtin-adb = ["uad-core/builtin-adb"]
self-update = ["flate2", "tar", "uad-core/self-update"]
no-self-update = []
wgpu = [] # Iced/wgpu is default
img = ["image", "iced/image"]
[dependencies]
uad-core = { path = "../uad-core", features = ["self-update"] }
uad-core = { path = "../uad-core", default-features = false }
iced.workspace = true
image = { workspace = true, optional = true }
rfd.workspace = true

View file

@ -519,10 +519,11 @@ impl Settings {
.spacing(10)
.align_y(Alignment::Center);
let backend_descr = text(
"Builtin: Uses embedded ADB (no external dependencies). System: Uses your installed adb binary.",
)
.style(style::Text::Commentary);
#[cfg(feature = "builtin-adb")]
let backend_description = "System: Uses your installed adb binary. Builtin: Uses embedded ADB (no external dependencies).";
#[cfg(not(feature = "builtin-adb"))]
let backend_description = "System: Uses your installed adb binary.";
let backend_descr = text(backend_description).style(style::Text::Commentary);
let version_row = row![
text("Version: ").size(14),