Files
guara/crates/guara-core/src/reconnect.rs
T
Lucas RayanandClaude Sonnet 5.5 4bb2397e3b
Release / Cria a release (push) Canceled after 0s
Release / CLI (linux-aarch64) (push) Canceled after 0s
Release / CLI (linux-x86_64) (push) Canceled after 0s
Release / CLI (macos-aarch64) (push) Canceled after 0s
Release / CLI (macos-x86_64) (push) Canceled after 0s
Release / CLI (windows-x86_64) (push) Canceled after 0s
Release / App desktop (linux-x86_64) (push) Canceled after 0s
Release / App desktop (macos-aarch64) (push) Canceled after 0s
Release / App desktop (macos-x86_64) (push) Canceled after 0s
Release / App desktop (windows-x86_64) (push) Canceled after 0s
Release / Publica a release (push) Canceled after 0s
feat: reconexão do disco, pausa por desconexão, sessões automáticas e organização (0.4.0)
- Reconhece o mesmo disco por tamanho + impressão digital quando volta com outro nome.
- Varredura pausa sozinha (sem perder nada) se o dispositivo parar de responder.
- Sessões salvas automaticamente (atômico) e listadas em Recentes.
- Organização ao recuperar (pastas, tipo, data, tudo junto) e checagem de espaço livre.
- Botão de escolher a origem também em sessões pausadas.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-18 19:32:00 -03:00

45 lines
1.4 KiB
Rust

//! Reencontra o disco de uma sessão quando ele foi desconectado e voltou com
//! outro nome (por exemplo `/dev/sda` virando `/dev/sdb`).
use crate::device;
use crate::source::{fingerprint, open_path, Source};
use std::path::Path;
use std::sync::Arc;
/// A origem é compatível com o que a sessão espera?
/// `size == 0` ou `fp == None` significam "não sei" e não reprovam.
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))
}
/// Procura entre os discos conectados o que corresponde à sessão.
/// Com impressão digital, exige igualdade; sem ela, só aceita se houver um único disco do mesmo tamanho.
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
}
}