CI / Format and clippy (push) Successful in 1m57s
CI / Dependency audit (push) Successful in 13s
CI / Check desktop app (Linux) (push) Successful in 3m54s
CI / Tests (Linux) (push) Failing after 7m25s
Release / Create release (push) Successful in 6s
Release / CLI (linux-aarch64) (push) Successful in 1m48s
Release / CLI (linux-x86_64) (push) Successful in 2m39s
Release / Desktop app (linux-aarch64) (push) Successful in 10m9s
Release / Desktop app (linux-x86_64) (push) Successful in 12m20s
Release / Desktop app (windows) (push) Successful in 7m32s
Release / Build latest.json (push) Successful in 5s
Completes the English-only standardization for code, comments, scripts and CI templates (UI/CLI-facing strings stay bilingual pt-BR/en, untouched). Covers the remaining crates/, apps/gui/ui/ and apps/gui/src-tauri/ comments, .gitea/ workflow and template comments, .githooks/ hooks, and the scripts/ source comments for the files already renamed in a prior commit (check.sh, generate-logo.py, install-hooks.sh). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VAyr8d7HuAdUGB6aA5xmDD
45 lines
1.5 KiB
Rust
45 lines
1.5 KiB
Rust
//! Re-identifies and reconnects a session's source disk when unplugged and reattached
|
|
//! under a different OS device node (e.g. `/dev/sda` becoming `/dev/sdb`).
|
|
|
|
use crate::device;
|
|
use crate::source::{fingerprint, open_path, Source};
|
|
use std::path::Path;
|
|
use std::sync::Arc;
|
|
|
|
/// Checks whether `src` matches the size and fingerprint expected by the session.
|
|
/// `size == 0` or `fp == None` mean unknown (legacy session) and do not reject the source.
|
|
pub fn matches(src: &dyn Source, size: u64, fp: Option<&str>) -> bool {
|
|
(size == 0 || src.size() == size) && fp.map_or(true, |f| fingerprint(src).as_deref() == Some(f))
|
|
}
|
|
|
|
/// Searches attached storage devices for the disk matching the session's fingerprint.
|
|
/// Requires an exact fingerprint match when present; otherwise accepts a unique size match.
|
|
pub fn find_matching_source(
|
|
size: u64,
|
|
fp: Option<&str>,
|
|
exclude: &[String],
|
|
) -> Option<(String, Arc<dyn Source>)> {
|
|
if size == 0 && fp.is_none() {
|
|
return None;
|
|
}
|
|
let mut found: Vec<(String, Arc<dyn Source>)> = vec![];
|
|
for d in device::list_devices() {
|
|
if !d.readable || exclude.contains(&d.path) || (size != 0 && d.size != size) {
|
|
continue;
|
|
}
|
|
let Ok(src) = open_path(Path::new(&d.path)) else {
|
|
continue;
|
|
};
|
|
if matches(src.as_ref(), size, fp) {
|
|
found.push((d.path, src));
|
|
}
|
|
}
|
|
if fp.is_some() {
|
|
found.into_iter().next()
|
|
} else if found.len() == 1 {
|
|
found.pop()
|
|
} else {
|
|
None
|
|
}
|
|
}
|