Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

76 changes: 36 additions & 40 deletions crates/yoop-cli/src/tui/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1078,16 +1078,15 @@ impl App {
Action::AddFiles(files) => {
self.state.share.selected_files.extend(files);
}
Action::RemoveFile(index) => {
if index < self.state.share.selected_files.len() {
self.state.share.selected_files.remove(index);
if self.state.share.selected_index >= self.state.share.selected_files.len()
&& self.state.share.selected_index > 0
{
self.state.share.selected_index -= 1;
}
Action::RemoveFile(index) if index < self.state.share.selected_files.len() => {
self.state.share.selected_files.remove(index);
if self.state.share.selected_index >= self.state.share.selected_files.len()
&& self.state.share.selected_index > 0
{
self.state.share.selected_index -= 1;
}
}
Action::RemoveFile(_) => {}
Action::ToggleFile(index) => {
self.state.share.selected_index = index;
}
Expand Down Expand Up @@ -1293,15 +1292,14 @@ impl App {
Action::AddExcludePattern(pattern) => {
self.state.sync.exclude_patterns.push(pattern);
}
Action::RemoveExcludePattern(index) => {
if index < self.state.sync.exclude_patterns.len() {
self.state.sync.exclude_patterns.remove(index);
if self.state.sync.selected_pattern_index
>= self.state.sync.exclude_patterns.len()
{
self.state.sync.selected_pattern_index =
self.state.sync.exclude_patterns.len().saturating_sub(1);
}
Action::RemoveExcludePattern(index)
if index < self.state.sync.exclude_patterns.len() =>
{
self.state.sync.exclude_patterns.remove(index);
if self.state.sync.selected_pattern_index >= self.state.sync.exclude_patterns.len()
{
self.state.sync.selected_pattern_index =
self.state.sync.exclude_patterns.len().saturating_sub(1);
}
}
Action::StartAddExcludePattern => {
Expand All @@ -1327,10 +1325,8 @@ impl App {
self.state.sync.focus = super::state::SyncFocus::ExcludePatterns;
}

Action::SelectDeviceIndex(index) => {
if index < self.views.devices.devices.len() {
self.state.devices.selected_index = index;
}
Action::SelectDeviceIndex(index) if index < self.views.devices.devices.len() => {
self.state.devices.selected_index = index;
}
Action::CycleTrustLevel => {
if let Some(device) = self.views.devices.get_selected_device(&self.state) {
Expand Down Expand Up @@ -1386,10 +1382,8 @@ impl App {
self.log_info("Devices list refreshed");
}

Action::SelectHistoryIndex(index) => {
if index < self.views.history.entries.len() {
self.state.history.selected_index = index;
}
Action::SelectHistoryIndex(index) if index < self.views.history.entries.len() => {
self.state.history.selected_index = index;
}
Action::ViewHistoryDetails => {
self.state.history.focus = super::state::HistoryFocus::Details;
Expand Down Expand Up @@ -1463,23 +1457,25 @@ impl App {
self.state.config.selected_setting = 0;
}
}
Action::SelectConfigSectionIndex(index) => {
if index < super::state::ConfigSection::all().len() {
self.state.config.selected_section = index;
self.state.config.selected_setting = 0;
}
Action::SelectConfigSectionIndex(index)
if index < super::state::ConfigSection::all().len() =>
{
self.state.config.selected_section = index;
self.state.config.selected_setting = 0;
}
Action::SelectConfigSetting(index) => {
if let Some(settings) = self.views.config.current_settings(&self.state.config) {
if index < settings.len() {
self.state.config.selected_setting = index;
}
}
Action::SelectConfigSetting(index)
if self
.views
.config
.current_settings(&self.state.config)
.is_some_and(|settings| index < settings.len()) =>
{
self.state.config.selected_setting = index;
}
Action::StartEditSetting => {
if self.state.config.focus == super::state::ConfigFocus::Settings {
self.views.config.start_edit(&mut self.state.config);
}
Action::StartEditSetting
if self.state.config.focus == super::state::ConfigFocus::Settings =>
{
self.views.config.start_edit(&mut self.state.config);
}
Action::UpdateEditBuffer(s) => {
self.state.config.edit_buffer = s;
Expand Down
4 changes: 2 additions & 2 deletions crates/yoop-cli/src/tui/components/file_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ impl FileList {
let size = if is_dir {
calculate_dir_size(path).unwrap_or(0)
} else {
std::fs::metadata(path).map(|m| m.len()).unwrap_or(0)
std::fs::metadata(path).map_or(0, |m| m.len())
};

let icon = if is_dir { "/" } else { "" };
Expand Down Expand Up @@ -168,7 +168,7 @@ fn calculate_total_size(files: &[PathBuf]) -> u64 {
if path.is_dir() {
calculate_dir_size(path).unwrap_or(0)
} else {
std::fs::metadata(path).map(|m| m.len()).unwrap_or(0)
std::fs::metadata(path).map_or(0, |m| m.len())
}
})
.sum()
Expand Down
9 changes: 4 additions & 5 deletions crates/yoop-cli/src/tui/components/status_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,9 @@ impl StatusBar {
let total: u64 = transfers.iter().map(|t| t.progress.total).sum();
let transferred: u64 = transfers.iter().map(|t| t.progress.transferred).sum();

if total == 0 {
0
} else {
((transferred * 100) / total) as u8
}
transferred
.saturating_mul(100)
.checked_div(total)
.map_or(0, |progress| progress as u8)
}
}
3 changes: 1 addition & 2 deletions crates/yoop-cli/src/tui/session/state_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,10 @@ fn is_process_alive(pid: u32) -> bool {
std::process::Command::new("tasklist")
.args(["/FI", &format!("PID eq {}", pid), "/NH"])
.output()
.map(|output| {
.is_ok_and(|output| {
let stdout = String::from_utf8_lossy(&output.stdout);
stdout.contains(&pid.to_string())
})
.unwrap_or(false)
}

/// Check if a process is alive (fallback for unsupported platforms).
Expand Down
3 changes: 1 addition & 2 deletions crates/yoop-cli/src/tui/views/devices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -459,8 +459,7 @@ impl DevicesView {
for device in store.list() {
let is_online = now
.duration_since(device.last_seen)
.map(|d| d.as_secs() < 300)
.unwrap_or(false);
.is_ok_and(|d| d.as_secs() < 300);

let trust_level = match device.trust_level {
yoop_core::config::TrustLevel::Full => "Full".to_string(),
Expand Down
2 changes: 1 addition & 1 deletion crates/yoop-cli/src/tui/views/share.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ impl ShareView {

let total_size: u64 = files
.iter()
.map(|p| std::fs::metadata(p).map(|m| m.len()).unwrap_or(0))
.map(|p| std::fs::metadata(p).map_or(0, |m| m.len()))
.sum();

let file_names: Vec<String> = files
Expand Down
15 changes: 12 additions & 3 deletions crates/yoop-core/src/clipboard/access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,10 @@ mod tests {
static CLIPBOARD_LOCK: Mutex<()> = Mutex::new(());

#[test]
#[cfg_attr(any(windows, target_os = "macos"), ignore)]
#[cfg_attr(
any(windows, target_os = "macos"),
ignore = "clipboard access is unreliable in headless CI"
)]
fn test_create_clipboard() {
let _lock = CLIPBOARD_LOCK.lock().unwrap();
let result = create_clipboard();
Expand All @@ -436,7 +439,10 @@ mod tests {
}

#[test]
#[cfg_attr(any(windows, target_os = "macos"), ignore)]
#[cfg_attr(
any(windows, target_os = "macos"),
ignore = "clipboard access is unreliable in headless CI"
)]
fn test_clipboard_text_roundtrip() {
let _lock = CLIPBOARD_LOCK.lock().unwrap();
let clipboard = create_clipboard();
Expand Down Expand Up @@ -466,7 +472,10 @@ mod tests {
}

#[test]
#[cfg_attr(any(windows, target_os = "macos"), ignore)]
#[cfg_attr(
any(windows, target_os = "macos"),
ignore = "clipboard access is unreliable in headless CI"
)]
fn test_content_hash_consistency() {
let _lock = CLIPBOARD_LOCK.lock().unwrap();
let clipboard = create_clipboard();
Expand Down
26 changes: 13 additions & 13 deletions crates/yoop-core/src/clipboard/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1867,7 +1867,7 @@ impl SyncSessionRunner {
/// Returns an error if sync fails.
#[allow(clippy::too_many_lines)]
pub async fn run(self) -> Result<(SyncStats, mpsc::Receiver<SyncEvent>)> {
let (event_tx, event_rx) = mpsc::channel(32);
let (event_tx, event_rx) = mpsc::channel(128);

let started_at = Instant::now();

Expand Down Expand Up @@ -1959,12 +1959,12 @@ impl SyncSessionRunner {
items_sent_clone.fetch_add(1, Ordering::SeqCst);
bytes_sent_clone.fetch_add(change.content.size(), Ordering::SeqCst);

let _ = event_tx_clone
.send(SyncEvent::Sent {
content_type: change.content.content_type(),
size: change.content.size(),
})
.await;
if let Err(e) = event_tx_clone.try_send(SyncEvent::Sent {
content_type: change.content.content_type(),
size: change.content.size(),
}) {
tracing::debug!("Outbound: dropping sync event: {}", e);
}

tracing::debug!("Outbound: change sent successfully");
}
Expand Down Expand Up @@ -2084,12 +2084,12 @@ impl SyncSessionRunner {
bytes_received_clone
.fetch_add(content_size, Ordering::SeqCst);

let _ = event_tx
.send(SyncEvent::Received {
content_type: changed.content_type,
size: changed.size,
})
.await;
if let Err(e) = event_tx.try_send(SyncEvent::Received {
content_type: changed.content_type,
size: changed.size,
}) {
tracing::debug!("Inbound: dropping sync event: {}", e);
}

tracing::info!(
"Inbound: clipboard updated successfully ({:?}, {} bytes)",
Expand Down
4 changes: 4 additions & 0 deletions crates/yoop-core/src/file/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ pub fn apply_permissions(path: &Path, permissions: Option<u32>) -> Result<()> {
/// Apply Unix file permissions to a file.
///
/// No-op on non-Unix platforms.
///
/// # Errors
///
/// This function does not currently return errors on non-Unix platforms.
#[cfg(not(unix))]
pub fn apply_permissions(_path: &Path, _permissions: Option<u32>) -> Result<()> {
Ok(())
Expand Down
4 changes: 1 addition & 3 deletions crates/yoop-core/src/history/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,7 @@ impl TransferHistoryEntry {
pub fn with_stats(mut self, bytes_transferred: u64, duration_secs: u64) -> Self {
self.bytes_transferred = bytes_transferred;
self.duration_secs = duration_secs;
if duration_secs > 0 {
self.speed_bps = Some(bytes_transferred / duration_secs);
}
self.speed_bps = bytes_transferred.checked_div(duration_secs);
self
}

Expand Down
6 changes: 2 additions & 4 deletions crates/yoop-core/src/migration/backup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ impl BackupManager {
})?;

backed_up_files.push((*file_name).to_string());
total_size += fs::metadata(&dest).map(|m| m.len()).unwrap_or(0);
total_size += fs::metadata(&dest).map_or(0, |m| m.len());
}
}

Expand Down Expand Up @@ -221,9 +221,7 @@ impl BackupManager {
return Ok(0);
}

manifest
.backups
.sort_by(|a, b| a.timestamp.cmp(&b.timestamp));
manifest.backups.sort_by_key(|backup| backup.timestamp);

let to_remove = manifest.backups.len() - self.max_backups;
let removed_backups: Vec<_> = manifest.backups.drain(..to_remove).collect();
Expand Down
17 changes: 9 additions & 8 deletions crates/yoop-core/src/sync/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,14 +194,15 @@ impl FileIndex {
content_hash: remote_entry.content_hash,
});
}
Some(local_entry) if local_entry.content_changed(remote_entry) => {
if remote_entry.is_newer_than(local_entry) {
ops.push(SyncOp::Modify {
path: remote_entry.path.clone(),
size: remote_entry.size,
content_hash: remote_entry.content_hash,
});
}
Some(local_entry)
if local_entry.content_changed(remote_entry)
&& remote_entry.is_newer_than(local_entry) =>
{
ops.push(SyncOp::Modify {
path: remote_entry.path.clone(),
size: remote_entry.size,
content_hash: remote_entry.content_hash,
});
}
_ => {}
}
Expand Down
20 changes: 9 additions & 11 deletions crates/yoop-core/src/transfer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -770,10 +770,9 @@ impl ShareSession {
(progress.total_bytes_transferred as f64 / elapsed) as u64;
}
let remaining = progress.total_bytes - progress.total_bytes_transferred;
if progress.speed_bps > 0 {
progress.eta =
Some(Duration::from_secs(remaining / progress.speed_bps));
}
progress.eta = remaining
.checked_div(progress.speed_bps)
.map(Duration::from_secs);
}
let _ = self.progress_tx.send(progress);
}
Expand Down Expand Up @@ -1602,10 +1601,9 @@ impl ReceiveSession {
(progress.total_bytes_transferred as f64 / elapsed) as u64;
}
let remaining = progress.total_bytes - progress.total_bytes_transferred;
if progress.speed_bps > 0 {
progress.eta =
Some(Duration::from_secs(remaining / progress.speed_bps));
}
progress.eta = remaining
.checked_div(progress.speed_bps)
.map(Duration::from_secs);
}
let _ = self.progress_tx.send(progress);
}
Expand Down Expand Up @@ -2062,9 +2060,9 @@ impl ReceiveSession {
progress.speed_bps = (progress.total_bytes_transferred as f64 / elapsed) as u64;
}
let remaining = progress.total_bytes - progress.total_bytes_transferred;
if progress.speed_bps > 0 {
progress.eta = Some(Duration::from_secs(remaining / progress.speed_bps));
}
progress.eta = remaining
.checked_div(progress.speed_bps)
.map(Duration::from_secs);
}
let _ = self.progress_tx.send(progress);
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion crates/yoop-core/src/transfer/resume.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ impl ResumeManager {
}
}

states.sort_by(|a, b| b.updated_at.cmp(&a.updated_at));
states.sort_by_key(|state| std::cmp::Reverse(state.updated_at));

Ok(states)
}
Expand Down
Loading
Loading