Compile the mount-table reader only where there is a mount table
`platform_volumes` has been gated to Linux since it was written, but the eight items it is built from were not, so every Android build compiled a `/proc/mounts` parser it could never call and then printed eight dead-code warnings about it. Real warnings hide in that kind of noise. Gated per item rather than moved into a module, because the file already draws the line that way one function above and two patterns for one idea is worse than a repeated attribute. The tests go with them. They parse a mount table and assert on names like `mmcblk0p1`, so they are as Linux-bound as the code they exercise, and `Path` turns out to be too -- only the reader borrows one, where `Volume` owns its own. Android now builds dr-plat with no warnings at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -27,7 +27,10 @@
|
||||
//! directory is reported alongside and weighted more heavily than the flag:
|
||||
//! a volume with `DCIM` on it is a camera card whatever sysfs believes.
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
// Only the mount-table reader below borrows a path; `Volume` owns one.
|
||||
#[cfg(target_os = "linux")]
|
||||
use std::path::Path;
|
||||
|
||||
/// Somewhere a card might be.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
@@ -136,6 +139,7 @@ fn platform_volumes() -> Vec<Volume> {
|
||||
}
|
||||
|
||||
/// One line of the mount table.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
struct Mount {
|
||||
device: String,
|
||||
@@ -147,6 +151,7 @@ struct Mount {
|
||||
///
|
||||
/// Split out from the reading so it can be tested against real tables without
|
||||
/// a card plugged in — which is the only way this file is testable at all.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn parse_mounts(table: &str) -> Vec<Mount> {
|
||||
table
|
||||
.lines()
|
||||
@@ -169,6 +174,7 @@ fn parse_mounts(table: &str) -> Vec<Mount> {
|
||||
/// A card is very often labelled with a space in it — `EOS DIGITAL` is what
|
||||
/// Canon writes — and mounted at `/run/media/duncan/EOS\040DIGITAL`. Without
|
||||
/// this the path does not exist and the card is invisible.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn unescape(field: &str) -> String {
|
||||
let mut out = String::with_capacity(field.len());
|
||||
let bytes = field.as_bytes();
|
||||
@@ -192,6 +198,7 @@ fn unescape(field: &str) -> String {
|
||||
///
|
||||
/// Excludes the pseudo-filesystems, which is most of the table, and anything
|
||||
/// not backed by a block device. A card reader always is.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn is_candidate(m: &Mount) -> bool {
|
||||
const FILESYSTEMS: &[&str] = &[
|
||||
// What cameras format cards as, in practice: FAT32 below 32 GB,
|
||||
@@ -204,6 +211,7 @@ fn is_candidate(m: &Mount) -> bool {
|
||||
}
|
||||
|
||||
/// Whether the desktop automounted this, which means it already decided.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn under_media_dir(mount_point: &Path) -> bool {
|
||||
let s = mount_point.to_string_lossy();
|
||||
s.starts_with("/run/media/") || s.starts_with("/media/") || s.starts_with("/mnt/media/")
|
||||
@@ -217,6 +225,7 @@ fn under_media_dir(mount_point: &Path) -> bool {
|
||||
/// lose only the `pN` suffix — strip naively and `mmcblk0p1` becomes
|
||||
/// `mmcblk`, which does not exist, and every SD card in an internal reader
|
||||
/// reports itself fixed.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn device_is_removable(device: &str) -> Option<bool> {
|
||||
let name = device.strip_prefix("/dev/")?;
|
||||
let disk = whole_disk(name);
|
||||
@@ -225,6 +234,7 @@ fn device_is_removable(device: &str) -> Option<bool> {
|
||||
}
|
||||
|
||||
/// The whole-disk name a partition belongs to.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn whole_disk(partition: &str) -> String {
|
||||
// `mmcblk0p1` -> `mmcblk0`, `nvme0n1p3` -> `nvme0n1`: these spell the
|
||||
// partition with a `p`, and the disk name legitimately ends in a digit.
|
||||
@@ -243,6 +253,7 @@ fn whole_disk(partition: &str) -> String {
|
||||
}
|
||||
|
||||
/// What to call a volume in a list.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn label_for(mount_point: &Path) -> String {
|
||||
mount_point
|
||||
.file_name()
|
||||
@@ -250,7 +261,9 @@ fn label_for(mount_point: &Path) -> String {
|
||||
.unwrap_or_else(|| mount_point.to_string_lossy().to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
// Reading `/proc/mounts` and naming block devices is what these test, so
|
||||
// they are as Linux-bound as the code above.
|
||||
#[cfg(all(test, target_os = "linux"))]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user