build(deps): updated dependencies and edition to 2024

This commit is contained in:
veeso
2025-03-15 14:15:45 +01:00
parent 8a9ba7745a
commit b0f314837e
46 changed files with 3621 additions and 2835 deletions

View File

@@ -1,6 +1,7 @@
# Changelog # Changelog
- [Changelog](#changelog) - [Changelog](#changelog)
- [0.17.0](#0170)
- [0.16.1](#0161) - [0.16.1](#0161)
- [0.16.0](#0160) - [0.16.0](#0160)
- [0.15.0](#0150) - [0.15.0](#0150)
@@ -39,6 +40,19 @@
--- ---
## 0.17.0
Released on ??
- Dependencies:
- `argh` to `0.1.13`
- `bytesize` to `2`
- `dirs` to `6`
- `magic-crypt` to `4`
- `notify` to `8`
- `ssh2-config` to `0.3`
- `remotefs-ssh` to `0.4`
## 0.16.1 ## 0.16.1
Released on 12/11/2024 Released on 12/11/2024

1816
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,7 @@
authors = ["Christian Visintin <christian.visintin@veeso.dev>"] authors = ["Christian Visintin <christian.visintin@veeso.dev>"]
categories = ["command-line-utilities"] categories = ["command-line-utilities"]
description = "termscp is a feature rich terminal file transfer and explorer with support for SCP/SFTP/FTP/Kube/S3/WebDAV" description = "termscp is a feature rich terminal file transfer and explorer with support for SCP/SFTP/FTP/Kube/S3/WebDAV"
edition = "2021" edition = "2024"
homepage = "https://termscp.veeso.dev" homepage = "https://termscp.veeso.dev"
include = ["src/**/*", "build.rs", "LICENSE", "README.md", "CHANGELOG.md"] include = ["src/**/*", "build.rs", "LICENSE", "README.md", "CHANGELOG.md"]
keywords = ["terminal", "ftp", "scp", "sftp", "tui"] keywords = ["terminal", "ftp", "scp", "sftp", "tui"]
@@ -10,7 +10,7 @@ license = "MIT"
name = "termscp" name = "termscp"
readme = "README.md" readme = "README.md"
repository = "https://github.com/veeso/termscp" repository = "https://github.com/veeso/termscp"
version = "0.16.1" version = "0.17.0"
[package.metadata.rpm] [package.metadata.rpm]
package = "termscp" package = "termscp"
@@ -33,10 +33,10 @@ path = "src/main.rs"
[dependencies] [dependencies]
argh = "^0.1" argh = "^0.1"
bitflags = "^2" bitflags = "^2"
bytesize = "^1" bytesize = "^2"
chrono = "^0.4" chrono = "^0.4"
content_inspector = "^0.2" content_inspector = "^0.2"
dirs = "^5.0" dirs = "^6"
edit = "^0.1" edit = "^0.1"
filetime = "^0.2" filetime = "^0.2"
hostname = "^0.4" hostname = "^0.4"
@@ -48,12 +48,12 @@ keyring = { version = "^3", optional = true, features = [
lazy-regex = "^3" lazy-regex = "^3"
lazy_static = "^1" lazy_static = "^1"
log = "^0.4" log = "^0.4"
magic-crypt = "^3" magic-crypt = "4"
notify = "6" notify = "8"
notify-rust = { version = "^4.5", default-features = false, features = ["d"] } notify-rust = { version = "^4", default-features = false, features = ["d"] }
nucleo = "0.5" nucleo = "0.5"
open = "^5.0" open = "^5.0"
rand = "^0.8.5" rand = "^0.9"
regex = "^1" regex = "^1"
remotefs = "^0.3" remotefs = "^0.3"
remotefs-aws-s3 = { version = "^0.3", default-features = false, features = [ remotefs-aws-s3 = { version = "^0.3", default-features = false, features = [
@@ -63,7 +63,7 @@ remotefs-aws-s3 = { version = "^0.3", default-features = false, features = [
remotefs-kube = "0.4" remotefs-kube = "0.4"
remotefs-webdav = "^0.2" remotefs-webdav = "^0.2"
rpassword = "^7" rpassword = "^7"
self_update = { version = "^0.41", default-features = false, features = [ self_update = { version = "^0.42", default-features = false, features = [
"rustls", "rustls",
"archive-tar", "archive-tar",
"archive-zip", "archive-zip",
@@ -72,10 +72,10 @@ self_update = { version = "^0.41", default-features = false, features = [
] } ] }
serde = { version = "^1", features = ["derive"] } serde = { version = "^1", features = ["derive"] }
simplelog = "^0.12" simplelog = "^0.12"
ssh2-config = "^0.2" ssh2-config = "^0.3"
tempfile = "^3" tempfile = "3"
thiserror = "^1" thiserror = "2"
tokio = { version = "=1.38.1", features = ["rt"] } tokio = { version = "1.44", features = ["rt"] }
toml = "^0.8" toml = "^0.8"
tui-realm-stdlib = "2" tui-realm-stdlib = "2"
tuirealm = "2" tuirealm = "2"
@@ -106,12 +106,12 @@ remotefs-smb = { version = "^0.3", optional = true }
[target."cfg(target_family = \"windows\")"] [target."cfg(target_family = \"windows\")"]
[target."cfg(target_family = \"windows\")".dependencies] [target."cfg(target_family = \"windows\")".dependencies]
remotefs-ftp = { version = "^0.2", features = ["native-tls"] } remotefs-ftp = { version = "^0.2", features = ["native-tls"] }
remotefs-ssh = "^0.4" remotefs-ssh = "^0.5"
[target."cfg(target_family = \"unix\")"] [target."cfg(target_family = \"unix\")"]
[target."cfg(target_family = \"unix\")".dependencies] [target."cfg(target_family = \"unix\")".dependencies]
remotefs-ftp = { version = "^0.2", features = ["vendored", "native-tls"] } remotefs-ftp = { version = "^0.2", features = ["vendored", "native-tls"] }
remotefs-ssh = { version = "^0.4", features = ["ssh2-vendored"] } remotefs-ssh = { version = "^0.5", features = ["ssh2-vendored"] }
uzers = "0.12" uzers = "0.12"
[profile.dev] [profile.dev]

View File

@@ -243,7 +243,7 @@ impl ActivityManager {
None => { None => {
return Err(format!( return Err(format!(
r#"Could not resolve bookmark name: "{bookmark_name}" no such bookmark"# r#"Could not resolve bookmark name: "{bookmark_name}" no such bookmark"#
)) ));
} }
Some(params) => params, Some(params) => params,
}; };
@@ -495,19 +495,28 @@ impl ActivityManager {
match ThemeProvider::new(theme_path.as_path()) { match ThemeProvider::new(theme_path.as_path()) {
Ok(provider) => provider, Ok(provider) => provider,
Err(err) => { Err(err) => {
error!("Could not initialize theme provider with file '{}': {}; using theme provider in degraded mode", theme_path.display(), err); error!(
"Could not initialize theme provider with file '{}': {}; using theme provider in degraded mode",
theme_path.display(),
err
);
ThemeProvider::degraded() ThemeProvider::degraded()
} }
} }
} }
None => { None => {
error!("This system doesn't provide a configuration directory; using theme provider in degraded mode"); error!(
"This system doesn't provide a configuration directory; using theme provider in degraded mode"
);
ThemeProvider::degraded() ThemeProvider::degraded()
} }
} }
} }
Err(err) => { Err(err) => {
error!("Could not initialize configuration directory: {}; using theme provider in degraded mode", err); error!(
"Could not initialize configuration directory: {}; using theme provider in degraded mode",
err
);
ThemeProvider::degraded() ThemeProvider::degraded()
} }
} }

View File

@@ -4,8 +4,8 @@
use std::io::{Read, Write}; use std::io::{Read, Write};
use serde::de::DeserializeOwned;
use serde::Serialize; use serde::Serialize;
use serde::de::DeserializeOwned;
use thiserror::Error; use thiserror::Error;
/// Contains the error for serializer/deserializer /// Contains the error for serializer/deserializer
@@ -63,7 +63,7 @@ where
return Err(SerializerError::new_ex( return Err(SerializerError::new_ex(
SerializerErrorKind::Serialization, SerializerErrorKind::Serialization,
err.to_string(), err.to_string(),
)) ));
} }
}; };
trace!("Serialized new bookmarks data: {}", data); trace!("Serialized new bookmarks data: {}", data);

View File

@@ -364,8 +364,16 @@ impl Formatter {
if fsentry.is_file() { if fsentry.is_file() {
// Get byte size // Get byte size
let size: ByteSize = ByteSize(fsentry.metadata().size); let size: ByteSize = ByteSize(fsentry.metadata().size);
let mut fmt = size.display().si().to_string();
// pad with up to len 10
let pad = 10usize.saturating_sub(fmt.len());
for _ in 0..pad {
fmt.push(' ');
}
format!("{cur_str}{prefix}{fmt}")
// Add to cur str, prefix and the key value // Add to cur str, prefix and the key value
format!("{cur_str}{prefix}{size:10}") //format!("{cur_str}{prefix}{size:10}", size = size.display().si())
} else if fsentry.metadata().symlink.is_some() { } else if fsentry.metadata().symlink.is_some() {
let size = ByteSize( let size = ByteSize(
fsentry fsentry
@@ -376,7 +384,14 @@ impl Formatter {
.to_string_lossy() .to_string_lossy()
.len() as u64, .len() as u64,
); );
format!("{cur_str}{prefix}{size:10}") let mut fmt = size.display().si().to_string();
// pad with up to len 10
let pad = 10usize.saturating_sub(fmt.len());
for _ in 0..pad {
fmt.push(' ');
}
format!("{cur_str}{prefix}{fmt}")
} else { } else {
// Add to cur str, prefix and the key value // Add to cur str, prefix and the key value
format!("{cur_str}{prefix} ") format!("{cur_str}{prefix} ")
@@ -596,7 +611,7 @@ mod tests {
assert_eq!( assert_eq!(
formatter.fmt(&entry), formatter.fmt(&entry),
format!( format!(
"bar.txt -rw-r--r-- root 8.2 KB {}", "bar.txt -rw-r--r-- root 8.2 kB {}",
fmt_time(t, "%b %d %Y %H:%M") fmt_time(t, "%b %d %Y %H:%M")
) )
); );
@@ -604,7 +619,7 @@ mod tests {
assert_eq!( assert_eq!(
formatter.fmt(&entry), formatter.fmt(&entry),
format!( format!(
"bar.txt -rw-r--r-- 0 8.2 KB {}", "bar.txt -rw-r--r-- 0 8.2 kB {}",
fmt_time(t, "%b %d %Y %H:%M") fmt_time(t, "%b %d %Y %H:%M")
) )
); );
@@ -627,7 +642,7 @@ mod tests {
assert_eq!( assert_eq!(
formatter.fmt(&entry), formatter.fmt(&entry),
format!( format!(
"piroparoporoperoperupup… -rw-r--r-- root 8.2 KB {}", "piroparoporoperoperupup… -rw-r--r-- root 8.2 kB {}",
fmt_time(t, "%b %d %Y %H:%M") fmt_time(t, "%b %d %Y %H:%M")
) )
); );
@@ -635,7 +650,7 @@ mod tests {
assert_eq!( assert_eq!(
formatter.fmt(&entry), formatter.fmt(&entry),
format!( format!(
"piroparoporoperoperupup… -rw-r--r-- 0 8.2 KB {}", "piroparoporoperoperupup… -rw-r--r-- 0 8.2 kB {}",
fmt_time(t, "%b %d %Y %H:%M") fmt_time(t, "%b %d %Y %H:%M")
) )
); );
@@ -658,7 +673,7 @@ mod tests {
assert_eq!( assert_eq!(
formatter.fmt(&entry), formatter.fmt(&entry),
format!( format!(
"bar.txt -????????? root 8.2 KB {}", "bar.txt -????????? root 8.2 kB {}",
fmt_time(t, "%b %d %Y %H:%M") fmt_time(t, "%b %d %Y %H:%M")
) )
); );
@@ -666,7 +681,7 @@ mod tests {
assert_eq!( assert_eq!(
formatter.fmt(&entry), formatter.fmt(&entry),
format!( format!(
"bar.txt -????????? 0 8.2 KB {}", "bar.txt -????????? 0 8.2 kB {}",
fmt_time(t, "%b %d %Y %H:%M") fmt_time(t, "%b %d %Y %H:%M")
) )
); );
@@ -689,7 +704,7 @@ mod tests {
assert_eq!( assert_eq!(
formatter.fmt(&entry), formatter.fmt(&entry),
format!( format!(
"bar.txt -????????? 0 8.2 KB {}", "bar.txt -????????? 0 8.2 kB {}",
fmt_time(t, "%b %d %Y %H:%M") fmt_time(t, "%b %d %Y %H:%M")
) )
); );
@@ -697,7 +712,7 @@ mod tests {
assert_eq!( assert_eq!(
formatter.fmt(&entry), formatter.fmt(&entry),
format!( format!(
"bar.txt -????????? 0 8.2 KB {}", "bar.txt -????????? 0 8.2 kB {}",
fmt_time(t, "%b %d %Y %H:%M") fmt_time(t, "%b %d %Y %H:%M")
) )
); );
@@ -774,8 +789,9 @@ mod tests {
#[test] #[test]
fn test_fs_explorer_formatter_all_together_now() { fn test_fs_explorer_formatter_all_together_now() {
let formatter: Formatter = let formatter: Formatter = Formatter::new(
Formatter::new("{NAME:16} {SYMLINK:12} {GROUP} {USER} {PEX} {SIZE} {ATIME:20:%a %b %d %Y %H:%M} {CTIME:20:%a %b %d %Y %H:%M} {MTIME:20:%a %b %d %Y %H:%M}"); "{NAME:16} {SYMLINK:12} {GROUP} {USER} {PEX} {SIZE} {ATIME:20:%a %b %d %Y %H:%M} {CTIME:20:%a %b %d %Y %H:%M} {MTIME:20:%a %b %d %Y %H:%M}",
);
// Directory (with symlink) // Directory (with symlink)
let t: SystemTime = SystemTime::now(); let t: SystemTime = SystemTime::now();
let entry = File { let entry = File {
@@ -792,12 +808,15 @@ mod tests {
mode: Some(UnixPex::from(0o755)), mode: Some(UnixPex::from(0o755)),
}, },
}; };
assert_eq!(formatter.fmt(&entry), format!( assert_eq!(
"projects -> project.info 0 0 lrwxr-xr-x 12 B {} {} {}", formatter.fmt(&entry),
fmt_time(t, "%a %b %d %Y %H:%M"), format!(
fmt_time(t, "%a %b %d %Y %H:%M"), "projects -> project.info 0 0 lrwxr-xr-x 12 B {} {} {}",
fmt_time(t, "%a %b %d %Y %H:%M"), fmt_time(t, "%a %b %d %Y %H:%M"),
)); fmt_time(t, "%a %b %d %Y %H:%M"),
fmt_time(t, "%a %b %d %Y %H:%M"),
)
);
// Directory without symlink // Directory without symlink
let entry = File { let entry = File {
path: PathBuf::from("/home/cvisintin/projects"), path: PathBuf::from("/home/cvisintin/projects"),
@@ -813,12 +832,15 @@ mod tests {
mode: Some(UnixPex::from(0o755)), mode: Some(UnixPex::from(0o755)),
}, },
}; };
assert_eq!(formatter.fmt(&entry), format!( assert_eq!(
"projects/ 0 0 drwxr-xr-x {} {} {}", formatter.fmt(&entry),
fmt_time(t, "%a %b %d %Y %H:%M"), format!(
fmt_time(t, "%a %b %d %Y %H:%M"), "projects/ 0 0 drwxr-xr-x {} {} {}",
fmt_time(t, "%a %b %d %Y %H:%M"), fmt_time(t, "%a %b %d %Y %H:%M"),
)); fmt_time(t, "%a %b %d %Y %H:%M"),
fmt_time(t, "%a %b %d %Y %H:%M"),
)
);
// File with symlink // File with symlink
let entry = File { let entry = File {
path: PathBuf::from("/bar.txt"), path: PathBuf::from("/bar.txt"),
@@ -834,12 +856,15 @@ mod tests {
mode: Some(UnixPex::from(0o644)), mode: Some(UnixPex::from(0o644)),
}, },
}; };
assert_eq!(formatter.fmt(&entry), format!( assert_eq!(
"bar.txt -> project.info 0 0 lrw-r--r-- 12 B {} {} {}", formatter.fmt(&entry),
fmt_time(t, "%a %b %d %Y %H:%M"), format!(
fmt_time(t, "%a %b %d %Y %H:%M"), "bar.txt -> project.info 0 0 lrw-r--r-- 12 B {} {} {}",
fmt_time(t, "%a %b %d %Y %H:%M"), fmt_time(t, "%a %b %d %Y %H:%M"),
)); fmt_time(t, "%a %b %d %Y %H:%M"),
fmt_time(t, "%a %b %d %Y %H:%M"),
)
);
// File without symlink // File without symlink
let entry = File { let entry = File {
path: PathBuf::from("/bar.txt"), path: PathBuf::from("/bar.txt"),
@@ -855,12 +880,15 @@ mod tests {
mode: Some(UnixPex::from(0o644)), mode: Some(UnixPex::from(0o644)),
}, },
}; };
assert_eq!(formatter.fmt(&entry), format!( assert_eq!(
"bar.txt 0 0 -rw-r--r-- 8.2 KB {} {} {}", formatter.fmt(&entry),
fmt_time(t, "%a %b %d %Y %H:%M"), format!(
fmt_time(t, "%a %b %d %Y %H:%M"), "bar.txt 0 0 -rw-r--r-- 8.2 kB {} {} {}",
fmt_time(t, "%a %b %d %Y %H:%M"), fmt_time(t, "%a %b %d %Y %H:%M"),
)); fmt_time(t, "%a %b %d %Y %H:%M"),
fmt_time(t, "%a %b %d %Y %H:%M"),
)
);
} }
#[test] #[test]

View File

@@ -523,7 +523,7 @@ mod tests {
assert_eq!( assert_eq!(
explorer.fmt_file(&entry), explorer.fmt_file(&entry),
format!( format!(
"bar.txt -rw-r--r-- root 8.2 KB {}", "bar.txt -rw-r--r-- root 8.2 kB {}",
fmt_time(t, "%b %d %Y %H:%M") fmt_time(t, "%b %d %Y %H:%M")
) )
); );
@@ -531,7 +531,7 @@ mod tests {
assert_eq!( assert_eq!(
explorer.fmt_file(&entry), explorer.fmt_file(&entry),
format!( format!(
"bar.txt -rw-r--r-- 0 8.2 KB {}", "bar.txt -rw-r--r-- 0 8.2 kB {}",
fmt_time(t, "%b %d %Y %H:%M") fmt_time(t, "%b %d %Y %H:%M")
) )
); );

View File

@@ -301,11 +301,13 @@ mod test {
#[test] #[test]
fn password_missing() { fn password_missing() {
assert!(FileTransferParams::new( assert!(
FileTransferProtocol::Scp, FileTransferParams::new(
ProtocolParams::AwsS3(AwsS3Params::new("omar", Some("eu-west-1"), Some("test"))) FileTransferProtocol::Scp,
) ProtocolParams::AwsS3(AwsS3Params::new("omar", Some("eu-west-1"), Some("test")))
.password_missing()); )
.password_missing()
);
assert_eq!( assert_eq!(
FileTransferParams::new( FileTransferParams::new(
FileTransferProtocol::Scp, FileTransferProtocol::Scp,

View File

@@ -1,8 +1,8 @@
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use remotefs::fs::{Metadata, UnixPex};
use remotefs::File; use remotefs::File;
use remotefs::fs::{Metadata, UnixPex};
use super::HostResult; use super::HostResult;

View File

@@ -5,8 +5,8 @@ use std::os::unix::fs::PermissionsExt as _;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use filetime::FileTime; use filetime::FileTime;
use remotefs::fs::{FileType, Metadata, UnixPex};
use remotefs::File; use remotefs::File;
use remotefs::fs::{FileType, Metadata, UnixPex};
use super::{HostBridge, HostResult}; use super::{HostBridge, HostResult};
use crate::host::{HostError, HostErrorType}; use crate::host::{HostError, HostErrorType};
@@ -105,8 +105,8 @@ impl HostBridge for Localhost {
)); ));
} }
let prev_dir: PathBuf = self.wrkdir.clone(); // Backup location let prev_dir: PathBuf = self.wrkdir.clone(); // Backup location
// Update working directory // Update working directory
// Change dir // Change dir
self.wrkdir = new_dir; self.wrkdir = new_dir;
// Scan new directory // Scan new directory
let pwd = self.pwd()?; let pwd = self.pwd()?;
@@ -135,7 +135,7 @@ impl HostBridge for Localhost {
HostErrorType::FileAlreadyExists, HostErrorType::FileAlreadyExists,
None, None,
dir_path.as_path(), dir_path.as_path(),
)) ));
} }
} }
} }
@@ -559,7 +559,7 @@ mod tests {
use std::io::Write; use std::io::Write;
use std::ops::AddAssign; use std::ops::AddAssign;
#[cfg(posix)] #[cfg(posix)]
use std::os::unix::fs::{symlink, PermissionsExt}; use std::os::unix::fs::{PermissionsExt, symlink};
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
@@ -661,9 +661,10 @@ mod tests {
#[should_panic] #[should_panic]
fn test_host_localhost_open_read_err_no_such_file() { fn test_host_localhost_open_read_err_no_such_file() {
let mut host: Localhost = Localhost::new(PathBuf::from("/dev")).ok().unwrap(); let mut host: Localhost = Localhost::new(PathBuf::from("/dev")).ok().unwrap();
assert!(host assert!(
.open_file(PathBuf::from("/bin/foo-bar-test-omar-123-456-789.txt").as_path()) host.open_file(PathBuf::from("/bin/foo-bar-test-omar-123-456-789.txt").as_path())
.is_ok()); .is_ok()
);
} }
#[test] #[test]
@@ -704,11 +705,13 @@ mod tests {
// Create sample file // Create sample file
assert!(StdFile::create(format!("{}/foo.txt", tmpdir.path().display()).as_str()).is_ok()); assert!(StdFile::create(format!("{}/foo.txt", tmpdir.path().display()).as_str()).is_ok());
// Create symlink // Create symlink
assert!(symlink( assert!(
format!("{}/foo.txt", tmpdir.path().display()), symlink(
format!("{}/bar.txt", tmpdir.path().display()) format!("{}/foo.txt", tmpdir.path().display()),
) format!("{}/bar.txt", tmpdir.path().display())
.is_ok()); )
.is_ok()
);
// Get dir // Get dir
let host: Localhost = Localhost::new(PathBuf::from(tmpdir.path())).ok().unwrap(); let host: Localhost = Localhost::new(PathBuf::from(tmpdir.path())).ok().unwrap();
let files: Vec<File> = host.files.clone(); let files: Vec<File> = host.files.clone();
@@ -744,19 +747,21 @@ mod tests {
assert!(host.mkdir(PathBuf::from("test_dir").as_path()).is_ok()); assert!(host.mkdir(PathBuf::from("test_dir").as_path()).is_ok());
let files: Vec<File> = host.files.clone(); let files: Vec<File> = host.files.clone();
assert_eq!(files.len(), 1); // There should be 1 file now assert_eq!(files.len(), 1); // There should be 1 file now
// Try to re-create directory // Try to re-create directory
assert!(host.mkdir(PathBuf::from("test_dir").as_path()).is_err()); assert!(host.mkdir(PathBuf::from("test_dir").as_path()).is_err());
// Try abs path // Try abs path
assert!(host assert!(
.mkdir_ex(PathBuf::from("/tmp/test_dir_123456789").as_path(), true) host.mkdir_ex(PathBuf::from("/tmp/test_dir_123456789").as_path(), true)
.is_ok()); .is_ok()
);
// Fail // Fail
assert!(host assert!(
.mkdir_ex( host.mkdir_ex(
PathBuf::from("/aaaa/oooooo/tmp/test_dir_123456789").as_path(), PathBuf::from("/aaaa/oooooo/tmp/test_dir_123456789").as_path(),
true true
) )
.is_err()); .is_err()
);
} }
#[test] #[test]
@@ -768,24 +773,26 @@ mod tests {
let mut host: Localhost = Localhost::new(PathBuf::from(tmpdir.path())).ok().unwrap(); let mut host: Localhost = Localhost::new(PathBuf::from(tmpdir.path())).ok().unwrap();
let files: Vec<File> = host.files.clone(); let files: Vec<File> = host.files.clone();
assert_eq!(files.len(), 1); // There should be 1 file now assert_eq!(files.len(), 1); // There should be 1 file now
// Remove file // Remove file
assert!(host.remove(files.get(0).unwrap()).is_ok()); assert!(host.remove(files.get(0).unwrap()).is_ok());
// There should be 0 files now // There should be 0 files now
let files: Vec<File> = host.files.clone(); let files: Vec<File> = host.files.clone();
assert_eq!(files.len(), 0); // There should be 0 files now assert_eq!(files.len(), 0); // There should be 0 files now
// Create directory // Create directory
assert!(host.mkdir(PathBuf::from("test_dir").as_path()).is_ok()); assert!(host.mkdir(PathBuf::from("test_dir").as_path()).is_ok());
// Delete directory // Delete directory
let files: Vec<File> = host.files.clone(); let files: Vec<File> = host.files.clone();
assert_eq!(files.len(), 1); // There should be 1 file now assert_eq!(files.len(), 1); // There should be 1 file now
assert!(host.remove(files.get(0).unwrap()).is_ok()); assert!(host.remove(files.get(0).unwrap()).is_ok());
// Remove unexisting directory // Remove unexisting directory
assert!(host assert!(
.remove(&make_fsentry(PathBuf::from("/a/b/c/d"), true)) host.remove(&make_fsentry(PathBuf::from("/a/b/c/d"), true))
.is_err()); .is_err()
assert!(host );
.remove(&make_fsentry(PathBuf::from("/aaaaaaa"), false)) assert!(
.is_err()); host.remove(&make_fsentry(PathBuf::from("/aaaaaaa"), false))
.is_err()
);
} }
#[test] #[test]
@@ -803,18 +810,20 @@ mod tests {
// Rename file // Rename file
let dst_path: PathBuf = let dst_path: PathBuf =
PathBuf::from(format!("{}/bar.txt", tmpdir.path().display()).as_str()); PathBuf::from(format!("{}/bar.txt", tmpdir.path().display()).as_str());
assert!(host assert!(
.rename(files.get(0).unwrap(), dst_path.as_path()) host.rename(files.get(0).unwrap(), dst_path.as_path())
.is_ok()); .is_ok()
);
// There should be still 1 file now, but named bar.txt // There should be still 1 file now, but named bar.txt
let files: Vec<File> = host.files.clone(); let files: Vec<File> = host.files.clone();
assert_eq!(files.len(), 1); // There should be 0 files now assert_eq!(files.len(), 1); // There should be 0 files now
assert_eq!(files.get(0).unwrap().name(), "bar.txt"); assert_eq!(files.get(0).unwrap().name(), "bar.txt");
// Fail // Fail
let bad_path: PathBuf = PathBuf::from("/asdailsjoidoewojdijow/ashdiuahu"); let bad_path: PathBuf = PathBuf::from("/asdailsjoidoewojdijow/ashdiuahu");
assert!(host assert!(
.rename(files.get(0).unwrap(), bad_path.as_path()) host.rename(files.get(0).unwrap(), bad_path.as_path())
.is_err()); .is_err()
);
} }
#[test] #[test]
@@ -853,12 +862,13 @@ mod tests {
// Chmod to dir // Chmod to dir
assert!(host.chmod(tmpdir.path(), UnixPex::from(0o750)).is_ok()); assert!(host.chmod(tmpdir.path(), UnixPex::from(0o750)).is_ok());
// Error // Error
assert!(host assert!(
.chmod( host.chmod(
Path::new("/tmp/krgiogoiegj/kwrgnoerig"), Path::new("/tmp/krgiogoiegj/kwrgnoerig"),
UnixPex::from(0o777) UnixPex::from(0o777)
) )
.is_err()); .is_err()
);
} }
#[cfg(posix)] #[cfg(posix)]
@@ -883,12 +893,13 @@ mod tests {
// Verify host has two files // Verify host has two files
assert_eq!(host.files.len(), 2); assert_eq!(host.files.len(), 2);
// Fail copy // Fail copy
assert!(host assert!(
.copy( host.copy(
&make_fsentry(PathBuf::from("/a/a7/a/a7a"), false), &make_fsentry(PathBuf::from("/a/a7/a/a7a"), false),
PathBuf::from("571k422i").as_path() PathBuf::from("571k422i").as_path()
) )
.is_err()); .is_err()
);
} }
#[cfg(posix)] #[cfg(posix)]
@@ -996,9 +1007,10 @@ mod tests {
assert!(host.symlink(Path::new("link.txt"), p.as_path()).is_ok()); assert!(host.symlink(Path::new("link.txt"), p.as_path()).is_ok());
// Fail symlink // Fail symlink
assert!(host.symlink(Path::new("link.txt"), p.as_path()).is_err()); assert!(host.symlink(Path::new("link.txt"), p.as_path()).is_err());
assert!(host assert!(
.symlink(Path::new("/tmp/oooo/aaaa"), p.as_path()) host.symlink(Path::new("/tmp/oooo/aaaa"), p.as_path())
.is_err()); .is_err()
);
} }
#[test] #[test]

View File

@@ -5,7 +5,7 @@
use self_update::backends::github::Update as GithubUpdater; use self_update::backends::github::Update as GithubUpdater;
pub use self_update::errors::Error as UpdateError; pub use self_update::errors::Error as UpdateError;
use self_update::update::Release as UpdRelease; use self_update::update::Release as UpdRelease;
use self_update::{cargo_crate_version, Status}; use self_update::{Status, cargo_crate_version};
use crate::utils::parser::parse_semver; use crate::utils::parser::parse_semver;

View File

@@ -16,7 +16,7 @@ use super::keys::{KeyStorage, KeyStorageError};
// Local // Local
use crate::config::{ use crate::config::{
bookmarks::{Bookmark, UserHosts}, bookmarks::{Bookmark, UserHosts},
serialization::{deserialize, serialize, SerializerError, SerializerErrorKind}, serialization::{SerializerError, SerializerErrorKind, deserialize, serialize},
}; };
use crate::filetransfer::FileTransferParams; use crate::filetransfer::FileTransferParams;
use crate::utils::crypto; use crate::utils::crypto;

View File

@@ -4,14 +4,14 @@
// Locals // Locals
// Ext // Ext
use std::fs::{create_dir, remove_file, File, OpenOptions}; use std::fs::{File, OpenOptions, create_dir, remove_file};
use std::io::Write; use std::io::Write;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::str::FromStr; use std::str::FromStr;
use std::string::ToString; use std::string::ToString;
use crate::config::params::{UserConfig, DEFAULT_NOTIFICATION_TRANSFER_THRESHOLD}; use crate::config::params::{DEFAULT_NOTIFICATION_TRANSFER_THRESHOLD, UserConfig};
use crate::config::serialization::{deserialize, serialize, SerializerError, SerializerErrorKind}; use crate::config::serialization::{SerializerError, SerializerErrorKind, deserialize, serialize};
use crate::explorer::GroupDirs; use crate::explorer::GroupDirs;
use crate::filetransfer::FileTransferProtocol; use crate::filetransfer::FileTransferProtocol;
@@ -480,9 +480,11 @@ mod tests {
// Change some stuff // Change some stuff
client.set_text_editor(PathBuf::from("/usr/bin/vim")); client.set_text_editor(PathBuf::from("/usr/bin/vim"));
client.set_default_protocol(FileTransferProtocol::Scp); client.set_default_protocol(FileTransferProtocol::Scp);
assert!(client assert!(
.add_ssh_key("192.168.1.31", "pi", "piroporopero") client
.is_ok()); .add_ssh_key("192.168.1.31", "pi", "piroporopero")
.is_ok()
);
assert!(client.write_config().is_ok()); assert!(client.write_config().is_ok());
// Istantiate a new client // Istantiate a new client
let client: ConfigClient = ConfigClient::new(cfg_path.as_path(), key_path.as_path()) let client: ConfigClient = ConfigClient::new(cfg_path.as_path(), key_path.as_path())
@@ -678,9 +680,11 @@ mod tests {
.unwrap(); .unwrap();
// Add a new key // Add a new key
let rsa_key: String = get_sample_rsa_key(); let rsa_key: String = get_sample_rsa_key();
assert!(client assert!(
.add_ssh_key("192.168.1.31", "pi", rsa_key.as_str()) client
.is_ok()); .add_ssh_key("192.168.1.31", "pi", rsa_key.as_str())
.is_ok()
);
// Iterate keys // Iterate keys
for key in client.iter_ssh_keys() { for key in client.iter_ssh_keys() {
let host: SshHost = client.get_ssh_key(key).ok().unwrap().unwrap(); let host: SshHost = client.get_ssh_key(key).ok().unwrap().unwrap();

View File

@@ -16,7 +16,7 @@ pub fn init(level: LogLevel) -> Result<(), String> {
Ok(None) => { Ok(None) => {
return Err(String::from( return Err(String::from(
"This system doesn't seem to support CACHE_DIR", "This system doesn't seem to support CACHE_DIR",
)) ));
} }
Err(err) => return Err(err), Err(err) => return Err(err),
}; };

View File

@@ -123,9 +123,11 @@ mod tests {
.ok() .ok()
.unwrap(); .unwrap();
// Add ssh key // Add ssh key
assert!(client assert!(
.add_ssh_key("192.168.1.31", "pi", "piroporopero") client
.is_ok()); .add_ssh_key("192.168.1.31", "pi", "piroporopero")
.is_ok()
);
// Create ssh key storage // Create ssh key storage
let storage: SshKeyStorage = SshKeyStorage::from(&client); let storage: SshKeyStorage = SshKeyStorage::from(&client);
// Verify key exists // Verify key exists
@@ -141,7 +143,9 @@ mod tests {
#[test] #[test]
fn sould_resolve_key_from_ssh2_config() { fn sould_resolve_key_from_ssh2_config() {
let rsa_key = test_helpers::create_sample_file_with_content("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDErJhQxEI0+VvhlXVUyh+vMCm7aXfCA/g633AG8ezD/5EylwchtAr2JCoBWnxn4zV8nI9dMqOgm0jO4IsXpKOjQojv+0VOH7I+cDlBg0tk4hFlvyyS6YviDAfDDln3jYUM+5QNDfQLaZlH2WvcJ3mkDxLVlI9MBX1BAeSmChLxwAvxALp2ncImNQLzDO9eHcig3dtMrEKkzXQowRW5Y7eUzg2+vvVq4H2DOjWwUndvB5sJkhEfTUVE7ID8ZdGJo60kUb/02dZYj+IbkAnMCsqktk0cg/4XFX82hEfRYFeb1arkysFisPU1DOb6QielL/axeTebVplaouYcXY0pFdJt root@8c50fd4c345a"); let rsa_key = test_helpers::create_sample_file_with_content(
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDErJhQxEI0+VvhlXVUyh+vMCm7aXfCA/g633AG8ezD/5EylwchtAr2JCoBWnxn4zV8nI9dMqOgm0jO4IsXpKOjQojv+0VOH7I+cDlBg0tk4hFlvyyS6YviDAfDDln3jYUM+5QNDfQLaZlH2WvcJ3mkDxLVlI9MBX1BAeSmChLxwAvxALp2ncImNQLzDO9eHcig3dtMrEKkzXQowRW5Y7eUzg2+vvVq4H2DOjWwUndvB5sJkhEfTUVE7ID8ZdGJo60kUb/02dZYj+IbkAnMCsqktk0cg/4XFX82hEfRYFeb1arkysFisPU1DOb6QielL/axeTebVplaouYcXY0pFdJt root@8c50fd4c345a",
);
let ssh_config_file = test_helpers::create_sample_file_with_content(format!( let ssh_config_file = test_helpers::create_sample_file_with_content(format!(
r#" r#"
Host test Host test

View File

@@ -8,7 +8,7 @@ use std::fs::OpenOptions;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::string::ToString; use std::string::ToString;
use crate::config::serialization::{deserialize, serialize, SerializerError, SerializerErrorKind}; use crate::config::serialization::{SerializerError, SerializerErrorKind, deserialize, serialize};
use crate::config::themes::Theme; use crate::config::themes::Theme;
/// ThemeProvider provides a high level API to communicate with the termscp theme /// ThemeProvider provides a high level API to communicate with the termscp theme

View File

@@ -7,7 +7,7 @@ mod change;
// -- export // -- export
use std::collections::HashMap; use std::collections::HashMap;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::mpsc::{channel, Receiver, RecvTimeoutError}; use std::sync::mpsc::{Receiver, RecvTimeoutError, channel};
use std::time::Duration; use std::time::Duration;
pub use change::FsChange; pub use change::FsChange;
@@ -245,9 +245,11 @@ mod test {
fn should_watch_path() { fn should_watch_path() {
let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap(); let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap();
let tempdir = TempDir::new().unwrap(); let tempdir = TempDir::new().unwrap();
assert!(watcher assert!(
.watch(tempdir.path(), Path::new("/tmp/test")) watcher
.is_ok()); .watch(tempdir.path(), Path::new("/tmp/test"))
.is_ok()
);
// check if in paths // check if in paths
assert_eq!( assert_eq!(
watcher.paths.get(tempdir.path()).unwrap(), watcher.paths.get(tempdir.path()).unwrap(),
@@ -261,16 +263,20 @@ mod test {
fn should_not_watch_path_if_subdir_of_watched_path() { fn should_not_watch_path_if_subdir_of_watched_path() {
let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap(); let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap();
let tempdir = TempDir::new().unwrap(); let tempdir = TempDir::new().unwrap();
assert!(watcher assert!(
.watch(tempdir.path(), Path::new("/tmp/test")) watcher
.is_ok()); .watch(tempdir.path(), Path::new("/tmp/test"))
.is_ok()
);
// watch subdir // watch subdir
let mut subdir = tempdir.path().to_path_buf(); let mut subdir = tempdir.path().to_path_buf();
subdir.push("abc/def"); subdir.push("abc/def");
// should return already watched // should return already watched
assert!(watcher assert!(
.watch(subdir.as_path(), Path::new("/tmp/test/abc/def")) watcher
.is_err()); .watch(subdir.as_path(), Path::new("/tmp/test/abc/def"))
.is_err()
);
// close tempdir // close tempdir
assert!(tempdir.close().is_ok()); assert!(tempdir.close().is_ok());
} }
@@ -279,9 +285,11 @@ mod test {
fn should_unwatch_path() { fn should_unwatch_path() {
let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap(); let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap();
let tempdir = TempDir::new().unwrap(); let tempdir = TempDir::new().unwrap();
assert!(watcher assert!(
.watch(tempdir.path(), Path::new("/tmp/test")) watcher
.is_ok()); .watch(tempdir.path(), Path::new("/tmp/test"))
.is_ok()
);
// unwatch // unwatch
assert!(watcher.unwatch(tempdir.path()).is_ok()); assert!(watcher.unwatch(tempdir.path()).is_ok());
assert!(watcher.paths.get(tempdir.path()).is_none()); assert!(watcher.paths.get(tempdir.path()).is_none());
@@ -293,9 +301,11 @@ mod test {
fn should_unwatch_path_when_subdir() { fn should_unwatch_path_when_subdir() {
let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap(); let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap();
let tempdir = TempDir::new().unwrap(); let tempdir = TempDir::new().unwrap();
assert!(watcher assert!(
.watch(tempdir.path(), Path::new("/tmp/test")) watcher
.is_ok()); .watch(tempdir.path(), Path::new("/tmp/test"))
.is_ok()
);
// unwatch // unwatch
let mut subdir = tempdir.path().to_path_buf(); let mut subdir = tempdir.path().to_path_buf();
subdir.push("abc/def"); subdir.push("abc/def");
@@ -318,9 +328,11 @@ mod test {
fn should_tell_whether_path_is_watched() { fn should_tell_whether_path_is_watched() {
let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap(); let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap();
let tempdir = TempDir::new().unwrap(); let tempdir = TempDir::new().unwrap();
assert!(watcher assert!(
.watch(tempdir.path(), Path::new("/tmp/test")) watcher
.is_ok()); .watch(tempdir.path(), Path::new("/tmp/test"))
.is_ok()
);
assert_eq!(watcher.watched(tempdir.path()), true); assert_eq!(watcher.watched(tempdir.path()), true);
let mut subdir = tempdir.path().to_path_buf(); let mut subdir = tempdir.path().to_path_buf();
subdir.push("abc/def"); subdir.push("abc/def");
@@ -336,9 +348,11 @@ mod test {
let mut watcher = FsWatcher::init(Duration::from_millis(100)).unwrap(); let mut watcher = FsWatcher::init(Duration::from_millis(100)).unwrap();
let tempdir = TempDir::new().unwrap(); let tempdir = TempDir::new().unwrap();
let tempdir_path = PathBuf::from(format!("/private{}", tempdir.path().display())); let tempdir_path = PathBuf::from(format!("/private{}", tempdir.path().display()));
assert!(watcher assert!(
.watch(tempdir_path.as_path(), Path::new("/tmp/test")) watcher
.is_ok()); .watch(tempdir_path.as_path(), Path::new("/tmp/test"))
.is_ok()
);
// create file // create file
let file_path = test_helpers::make_file_at(tempdir_path.as_path(), "test.txt").unwrap(); let file_path = test_helpers::make_file_at(tempdir_path.as_path(), "test.txt").unwrap();
// wait // wait
@@ -362,9 +376,11 @@ mod test {
let mut watcher = FsWatcher::init(Duration::from_millis(100)).unwrap(); let mut watcher = FsWatcher::init(Duration::from_millis(100)).unwrap();
let tempdir = TempDir::new().unwrap(); let tempdir = TempDir::new().unwrap();
let tempdir_path = PathBuf::from(format!("/private{}", tempdir.path().display())); let tempdir_path = PathBuf::from(format!("/private{}", tempdir.path().display()));
assert!(watcher assert!(
.watch(tempdir_path.as_path(), Path::new("/tmp/test")) watcher
.is_ok()); .watch(tempdir_path.as_path(), Path::new("/tmp/test"))
.is_ok()
);
// create file // create file
let file_path = test_helpers::make_file_at(tempdir_path.as_path(), "test.txt").unwrap(); let file_path = test_helpers::make_file_at(tempdir_path.as_path(), "test.txt").unwrap();
std::thread::sleep(Duration::from_millis(500)); std::thread::sleep(Duration::from_millis(500));
@@ -424,9 +440,11 @@ mod test {
fn should_poll_nothing() { fn should_poll_nothing() {
let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap(); let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap();
let tempdir = TempDir::new().unwrap(); let tempdir = TempDir::new().unwrap();
assert!(watcher assert!(
.watch(tempdir.path(), Path::new("/tmp/test")) watcher
.is_ok()); .watch(tempdir.path(), Path::new("/tmp/test"))
.is_ok()
);
assert!(watcher.poll().ok().unwrap().is_none()); assert!(watcher.poll().ok().unwrap().is_none());
// close tempdir // close tempdir
assert!(tempdir.close().is_ok()); assert!(tempdir.close().is_ok());
@@ -437,9 +455,11 @@ mod test {
fn should_get_watched_paths() { fn should_get_watched_paths() {
let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap(); let mut watcher = FsWatcher::init(Duration::from_secs(5)).unwrap();
assert!(watcher.watch(Path::new("/tmp"), Path::new("/tmp")).is_ok()); assert!(watcher.watch(Path::new("/tmp"), Path::new("/tmp")).is_ok());
assert!(watcher assert!(
.watch(Path::new("/home"), Path::new("/home")) watcher
.is_ok()); .watch(Path::new("/home"), Path::new("/home"))
.is_ok()
);
let mut watched_paths = watcher.watched_paths(); let mut watched_paths = watcher.watched_paths();
watched_paths.sort(); watched_paths.sort();
assert_eq!(watched_paths, vec![Path::new("/home"), Path::new("/tmp")]); assert_eq!(watched_paths, vec![Path::new("/home"), Path::new("/tmp")]);

View File

@@ -4,11 +4,11 @@
// Locals // Locals
use super::{AuthActivity, FileTransferParams, FormTab, HostBridgeProtocol}; use super::{AuthActivity, FileTransferParams, FormTab, HostBridgeProtocol};
use crate::filetransfer::HostBridgeParams;
use crate::filetransfer::params::{ use crate::filetransfer::params::{
AwsS3Params, GenericProtocolParams, KubeProtocolParams, ProtocolParams, SmbParams, AwsS3Params, GenericProtocolParams, KubeProtocolParams, ProtocolParams, SmbParams,
WebDAVProtocolParams, WebDAVProtocolParams,
}; };
use crate::filetransfer::HostBridgeParams;
impl AuthActivity { impl AuthActivity {
/// Delete bookmark /// Delete bookmark

View File

@@ -10,14 +10,13 @@ use tuirealm::{Component, Event, MockComponent, NoUserEvent, State, StateValue};
use super::{FileTransferProtocol, FormMsg, Msg, UiMsg}; use super::{FileTransferProtocol, FormMsg, Msg, UiMsg};
use crate::ui::activities::auth::{ use crate::ui::activities::auth::{
FormTab, HostBridgeProtocol, UiAuthFormMsg, HOST_BRIDGE_RADIO_PROTOCOL_FTP, FormTab, HOST_BRIDGE_RADIO_PROTOCOL_FTP, HOST_BRIDGE_RADIO_PROTOCOL_FTPS,
HOST_BRIDGE_RADIO_PROTOCOL_FTPS, HOST_BRIDGE_RADIO_PROTOCOL_KUBE, HOST_BRIDGE_RADIO_PROTOCOL_KUBE, HOST_BRIDGE_RADIO_PROTOCOL_LOCALHOST,
HOST_BRIDGE_RADIO_PROTOCOL_LOCALHOST, HOST_BRIDGE_RADIO_PROTOCOL_S3, HOST_BRIDGE_RADIO_PROTOCOL_S3, HOST_BRIDGE_RADIO_PROTOCOL_SCP, HOST_BRIDGE_RADIO_PROTOCOL_SFTP,
HOST_BRIDGE_RADIO_PROTOCOL_SCP, HOST_BRIDGE_RADIO_PROTOCOL_SFTP, HOST_BRIDGE_RADIO_PROTOCOL_SMB, HOST_BRIDGE_RADIO_PROTOCOL_WEBDAV, HostBridgeProtocol,
HOST_BRIDGE_RADIO_PROTOCOL_SMB, HOST_BRIDGE_RADIO_PROTOCOL_WEBDAV, REMOTE_RADIO_PROTOCOL_FTP, REMOTE_RADIO_PROTOCOL_FTP, REMOTE_RADIO_PROTOCOL_FTPS, REMOTE_RADIO_PROTOCOL_KUBE,
REMOTE_RADIO_PROTOCOL_FTPS, REMOTE_RADIO_PROTOCOL_KUBE, REMOTE_RADIO_PROTOCOL_S3, REMOTE_RADIO_PROTOCOL_S3, REMOTE_RADIO_PROTOCOL_SCP, REMOTE_RADIO_PROTOCOL_SFTP,
REMOTE_RADIO_PROTOCOL_SCP, REMOTE_RADIO_PROTOCOL_SFTP, REMOTE_RADIO_PROTOCOL_SMB, REMOTE_RADIO_PROTOCOL_SMB, REMOTE_RADIO_PROTOCOL_WEBDAV, UiAuthFormMsg,
REMOTE_RADIO_PROTOCOL_WEBDAV,
}; };
// -- protocol // -- protocol
@@ -93,10 +92,10 @@ impl Component<Msg, NoUserEvent> for RemoteProtocolRadio {
code: Key::Down, .. code: Key::Down, ..
}) => return Some(Msg::Ui(UiMsg::Remote(UiAuthFormMsg::ProtocolBlurDown))), }) => return Some(Msg::Ui(UiMsg::Remote(UiAuthFormMsg::ProtocolBlurDown))),
Event::Keyboard(KeyEvent { code: Key::Up, .. }) => { Event::Keyboard(KeyEvent { code: Key::Up, .. }) => {
return Some(Msg::Ui(UiMsg::Remote(UiAuthFormMsg::ProtocolBlurUp))) return Some(Msg::Ui(UiMsg::Remote(UiAuthFormMsg::ProtocolBlurUp)));
} }
Event::Keyboard(KeyEvent { code: Key::Tab, .. }) => { Event::Keyboard(KeyEvent { code: Key::Tab, .. }) => {
return Some(Msg::Ui(UiMsg::Remote(UiAuthFormMsg::ParamsFormBlur))) return Some(Msg::Ui(UiMsg::Remote(UiAuthFormMsg::ParamsFormBlur)));
} }
Event::Keyboard(KeyEvent { Event::Keyboard(KeyEvent {
code: Key::BackTab, .. code: Key::BackTab, ..
@@ -228,10 +227,10 @@ impl Component<Msg, NoUserEvent> for HostBridgeProtocolRadio {
code: Key::Down, .. code: Key::Down, ..
}) => return Some(Msg::Ui(UiMsg::HostBridge(UiAuthFormMsg::ProtocolBlurDown))), }) => return Some(Msg::Ui(UiMsg::HostBridge(UiAuthFormMsg::ProtocolBlurDown))),
Event::Keyboard(KeyEvent { code: Key::Up, .. }) => { Event::Keyboard(KeyEvent { code: Key::Up, .. }) => {
return Some(Msg::Ui(UiMsg::HostBridge(UiAuthFormMsg::ProtocolBlurUp))) return Some(Msg::Ui(UiMsg::HostBridge(UiAuthFormMsg::ProtocolBlurUp)));
} }
Event::Keyboard(KeyEvent { code: Key::Tab, .. }) => { Event::Keyboard(KeyEvent { code: Key::Tab, .. }) => {
return Some(Msg::Ui(UiMsg::HostBridge(UiAuthFormMsg::ParamsFormBlur))) return Some(Msg::Ui(UiMsg::HostBridge(UiAuthFormMsg::ParamsFormBlur)));
} }
Event::Keyboard(KeyEvent { Event::Keyboard(KeyEvent {
code: Key::BackTab, .. code: Key::BackTab, ..

View File

@@ -5,8 +5,8 @@
use std::env; use std::env;
use super::{AuthActivity, FileTransferParams, FileTransferProtocol, FormTab, HostBridgeProtocol}; use super::{AuthActivity, FileTransferParams, FileTransferProtocol, FormTab, HostBridgeProtocol};
use crate::filetransfer::params::ProtocolParams;
use crate::filetransfer::HostBridgeParams; use crate::filetransfer::HostBridgeParams;
use crate::filetransfer::params::ProtocolParams;
use crate::system::auto_update::{Release, Update, UpdateStatus}; use crate::system::auto_update::{Release, Update, UpdateStatus};
use crate::system::notifications::Notification; use crate::system::notifications::Notification;

View File

@@ -17,7 +17,7 @@ use tuirealm::application::PollStrategy;
use tuirealm::listener::EventListenerCfg; use tuirealm::listener::EventListenerCfg;
use tuirealm::{Application, NoUserEvent, Update}; use tuirealm::{Application, NoUserEvent, Update};
use super::{Activity, Context, ExitReason, CROSSTERM_MAX_POLL}; use super::{Activity, CROSSTERM_MAX_POLL, Context, ExitReason};
use crate::config::themes::Theme; use crate::config::themes::Theme;
use crate::filetransfer::{FileTransferParams, FileTransferProtocol}; use crate::filetransfer::{FileTransferParams, FileTransferProtocol};
use crate::system::bookmarks_client::BookmarksClient; use crate::system::bookmarks_client::BookmarksClient;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -167,7 +167,9 @@ impl FileTransferActivity {
} }
} else { } else {
// Do not synchronize, disable sync browsing and return // Do not synchronize, disable sync browsing and return
trace!("The user doesn't want to create the directory; disabling synchronized browsing"); trace!(
"The user doesn't want to create the directory; disabling synchronized browsing"
);
self.log( self.log(
LogLevel::Warn, LogLevel::Warn,
format!("Refused to create '{name}'; synchronized browsing disabled"), format!("Refused to create '{name}'; synchronized browsing disabled"),

View File

@@ -7,8 +7,8 @@ use std::io::Read;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::time::SystemTime; use std::time::SystemTime;
use remotefs::fs::Metadata;
use remotefs::File; use remotefs::File;
use remotefs::fs::Metadata;
use super::{FileTransferActivity, LogLevel, SelectedFile, TransferPayload}; use super::{FileTransferActivity, LogLevel, SelectedFile, TransferPayload};
@@ -221,10 +221,7 @@ impl FileTransferActivity {
/// Edit file on remote host /// Edit file on remote host
fn edit_remote_file(&mut self, file: File) -> Result<(), String> { fn edit_remote_file(&mut self, file: File) -> Result<(), String> {
// Create temp file // Create temp file
let tmpfile: PathBuf = match self.download_file_as_temp(&file) { let tmpfile = self.download_file_as_temp(&file)?;
Ok(p) => p,
Err(err) => return Err(err),
};
// Download file // Download file
let file_name = file.name(); let file_name = file.name();
let file_path = file.path().to_path_buf(); let file_path = file.path().to_path_buf();
@@ -243,7 +240,7 @@ impl FileTransferActivity {
"Could not stat \"{}\": {}", "Could not stat \"{}\": {}",
tmpfile.as_path().display(), tmpfile.as_path().display(),
err err
)) ));
} }
}; };
// Edit file // Edit file
@@ -256,7 +253,7 @@ impl FileTransferActivity {
"Could not stat \"{}\": {}", "Could not stat \"{}\": {}",
tmpfile.as_path().display(), tmpfile.as_path().display(),
err err
)) ));
} }
}; };
// Check if file has changed // Check if file has changed
@@ -282,7 +279,7 @@ impl FileTransferActivity {
"Could not stat \"{}\": {}", "Could not stat \"{}\": {}",
tmpfile.as_path().display(), tmpfile.as_path().display(),
err err
)) ));
} }
}; };
// Send file // Send file

View File

@@ -4,8 +4,8 @@ use regex::Regex;
use remotefs::File; use remotefs::File;
use wildmatch::WildMatch; use wildmatch::WildMatch;
use crate::ui::activities::filetransfer::lib::browser::FileExplorerTab;
use crate::ui::activities::filetransfer::FileTransferActivity; use crate::ui::activities::filetransfer::FileTransferActivity;
use crate::ui::activities::filetransfer::lib::browser::FileExplorerTab;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Filter { pub enum Filter {

View File

@@ -2,8 +2,8 @@
//! //!
//! `filetransfer_activiy` is the module which implements the Filetransfer activity, which is the main activity afterall //! `filetransfer_activiy` is the module which implements the Filetransfer activity, which is the main activity afterall
use remotefs::fs::UnixPex;
use remotefs::File; use remotefs::File;
use remotefs::fs::UnixPex;
use tuirealm::{State, StateValue}; use tuirealm::{State, StateValue};
use super::browser::FileExplorerTab; use super::browser::FileExplorerTab;

View File

@@ -16,12 +16,12 @@ mod transfer;
pub use misc::FooterBar; pub use misc::FooterBar;
pub use popups::{ pub use popups::{
ChmodPopup, CopyPopup, DeletePopup, DisconnectPopup, ErrorPopup, ExecPopup, FatalPopup, ATTR_FILES, ChmodPopup, CopyPopup, DeletePopup, DisconnectPopup, ErrorPopup, ExecPopup,
FileInfoPopup, FilterPopup, GotoPopup, KeybindingsPopup, MkdirPopup, NewfilePopup, FatalPopup, FileInfoPopup, FilterPopup, GotoPopup, KeybindingsPopup, MkdirPopup, NewfilePopup,
OpenWithPopup, ProgressBarFull, ProgressBarPartial, QuitPopup, RenamePopup, ReplacePopup, OpenWithPopup, ProgressBarFull, ProgressBarPartial, QuitPopup, RenamePopup, ReplacePopup,
ReplacingFilesListPopup, SaveAsPopup, SortingPopup, StatusBarLocal, StatusBarRemote, ReplacingFilesListPopup, SaveAsPopup, SortingPopup, StatusBarLocal, StatusBarRemote,
SymlinkPopup, SyncBrowsingMkdirPopup, WaitPopup, WalkdirWaitPopup, WatchedPathsList, SymlinkPopup, SyncBrowsingMkdirPopup, WaitPopup, WalkdirWaitPopup, WatchedPathsList,
WatcherPopup, ATTR_FILES, WatcherPopup,
}; };
pub use transfer::{ExplorerFind, ExplorerFuzzy, ExplorerLocal, ExplorerRemote}; pub use transfer::{ExplorerFind, ExplorerFuzzy, ExplorerLocal, ExplorerRemote};

View File

@@ -20,7 +20,7 @@ use tuirealm::{Component, Event, MockComponent, NoUserEvent, State, StateValue};
use uzers::{get_group_by_gid, get_user_by_uid}; use uzers::{get_group_by_gid, get_user_by_uid};
pub use self::chmod::ChmodPopup; pub use self::chmod::ChmodPopup;
pub use self::goto::{GotoPopup, ATTR_FILES}; pub use self::goto::{ATTR_FILES, GotoPopup};
use super::super::Browser; use super::super::Browser;
use super::{Msg, PendingActionMsg, TransferMsg, UiMsg}; use super::{Msg, PendingActionMsg, TransferMsg, UiMsg};
use crate::explorer::FileSorting; use crate::explorer::FileSorting;

View File

@@ -90,7 +90,9 @@ impl FileTransferActivity {
/// Set text editor to use /// Set text editor to use
pub(super) fn setup_text_editor(&self) { pub(super) fn setup_text_editor(&self) {
env::set_var("EDITOR", self.config().get_text_editor()); unsafe {
env::set_var("EDITOR", self.config().get_text_editor());
}
} }
/// Convert a path to absolute according to host explorer /// Convert a path to absolute according to host explorer
@@ -262,22 +264,24 @@ impl FileTransferActivity {
.map(|x| vec![TextSpan::from(self.host_bridge().fmt_file(x))]) .map(|x| vec![TextSpan::from(self.host_bridge().fmt_file(x))])
.collect(); .collect();
// Update content and title // Update content and title
assert!(self assert!(
.app self.app
.attr( .attr(
&Id::ExplorerHostBridge, &Id::ExplorerHostBridge,
Attribute::Content, Attribute::Content,
AttrValue::Table(files) AttrValue::Table(files)
) )
.is_ok()); .is_ok()
assert!(self );
.app assert!(
.attr( self.app
&Id::ExplorerHostBridge, .attr(
Attribute::Title, &Id::ExplorerHostBridge,
AttrValue::Title((hostname, Alignment::Left)) Attribute::Title,
) AttrValue::Title((hostname, Alignment::Left))
.is_ok()); )
.is_ok()
);
} }
/// Update remote file list /// Update remote file list
@@ -307,22 +311,24 @@ impl FileTransferActivity {
.map(|x| vec![TextSpan::from(self.remote().fmt_file(x))]) .map(|x| vec![TextSpan::from(self.remote().fmt_file(x))])
.collect(); .collect();
// Update content and title // Update content and title
assert!(self assert!(
.app self.app
.attr( .attr(
&Id::ExplorerRemote, &Id::ExplorerRemote,
Attribute::Content, Attribute::Content,
AttrValue::Table(files) AttrValue::Table(files)
) )
.is_ok()); .is_ok()
assert!(self );
.app assert!(
.attr( self.app
&Id::ExplorerRemote, .attr(
Attribute::Title, &Id::ExplorerRemote,
AttrValue::Title((hostname, Alignment::Left)) Attribute::Title,
) AttrValue::Title((hostname, Alignment::Left))
.is_ok()); )
.is_ok()
);
} }
/// Update log box /// Update log box
@@ -361,61 +367,67 @@ impl FileTransferActivity {
.add_col(TextSpan::from("]: ")) .add_col(TextSpan::from("]: "))
.add_col(TextSpan::from(record.msg.as_str())); .add_col(TextSpan::from(record.msg.as_str()));
} }
assert!(self assert!(
.app self.app
.attr( .attr(
&Id::Log, &Id::Log,
Attribute::Content, Attribute::Content,
AttrValue::Table(table.build()) AttrValue::Table(table.build())
) )
.is_ok()); .is_ok()
);
} }
pub(super) fn update_progress_bar(&mut self, filename: String) { pub(super) fn update_progress_bar(&mut self, filename: String) {
assert!(self assert!(
.app self.app
.attr( .attr(
&Id::ProgressBarFull, &Id::ProgressBarFull,
Attribute::Text, Attribute::Text,
AttrValue::String(self.transfer.full.to_string()) AttrValue::String(self.transfer.full.to_string())
) )
.is_ok()); .is_ok()
assert!(self );
.app assert!(
.attr( self.app
&Id::ProgressBarFull, .attr(
Attribute::Value, &Id::ProgressBarFull,
AttrValue::Payload(PropPayload::One(PropValue::F64( Attribute::Value,
self.transfer.full.calc_progress() AttrValue::Payload(PropPayload::One(PropValue::F64(
))) self.transfer.full.calc_progress()
) )))
.is_ok()); )
assert!(self .is_ok()
.app );
.attr( assert!(
&Id::ProgressBarPartial, self.app
Attribute::Text, .attr(
AttrValue::String(self.transfer.partial.to_string()) &Id::ProgressBarPartial,
) Attribute::Text,
.is_ok()); AttrValue::String(self.transfer.partial.to_string())
assert!(self )
.app .is_ok()
.attr( );
&Id::ProgressBarPartial, assert!(
Attribute::Value, self.app
AttrValue::Payload(PropPayload::One(PropValue::F64( .attr(
self.transfer.partial.calc_progress() &Id::ProgressBarPartial,
))) Attribute::Value,
) AttrValue::Payload(PropPayload::One(PropValue::F64(
.is_ok()); self.transfer.partial.calc_progress()
assert!(self )))
.app )
.attr( .is_ok()
&Id::ProgressBarPartial, );
Attribute::Title, assert!(
AttrValue::Title((filename, Alignment::Center)) self.app
) .attr(
.is_ok()); &Id::ProgressBarPartial,
Attribute::Title,
AttrValue::Title((filename, Alignment::Center))
)
.is_ok()
);
} }
/// Finalize find process /// Finalize find process
@@ -450,14 +462,15 @@ impl FileTransferActivity {
.iter_files() .iter_files()
.map(|x| vec![TextSpan::from(self.found().unwrap().fmt_file(x))]) .map(|x| vec![TextSpan::from(self.found().unwrap().fmt_file(x))])
.collect(); .collect();
assert!(self assert!(
.app self.app
.attr( .attr(
&Id::ExplorerFind, &Id::ExplorerFind,
Attribute::Content, Attribute::Content,
AttrValue::Table(files) AttrValue::Table(files)
) )
.is_ok()); .is_ok()
);
} }
pub(super) fn update_browser_file_list(&mut self) { pub(super) fn update_browser_file_list(&mut self) {

View File

@@ -28,7 +28,7 @@ use session::TransferPayload;
use tempfile::TempDir; use tempfile::TempDir;
use tuirealm::{Application, EventListenerCfg, NoUserEvent}; use tuirealm::{Application, EventListenerCfg, NoUserEvent};
use super::{Activity, Context, ExitReason, CROSSTERM_MAX_POLL}; use super::{Activity, CROSSTERM_MAX_POLL, Context, ExitReason};
use crate::config::themes::Theme; use crate::config::themes::Theme;
use crate::explorer::{FileExplorer, FileSorting}; use crate::explorer::{FileExplorer, FileSorting};
use crate::filetransfer::{ use crate::filetransfer::{

View File

@@ -1239,7 +1239,7 @@ impl FileTransferActivity {
None => { None => {
return Err(String::from( return Err(String::from(
"Could not create tempfile: cache not available", "Could not create tempfile: cache not available",
)) ));
} }
}; };
// Download file // Download file

View File

@@ -8,8 +8,8 @@ use remotefs::fs::File;
use tuirealm::props::{AttrValue, Attribute}; use tuirealm::props::{AttrValue, Attribute};
use tuirealm::{State, StateValue, Update}; use tuirealm::{State, StateValue, Update};
use super::actions::walkdir::WalkdirError;
use super::actions::SelectedFile; use super::actions::SelectedFile;
use super::actions::walkdir::WalkdirError;
use super::browser::{FileExplorerTab, FoundExplorerTab}; use super::browser::{FileExplorerTab, FoundExplorerTab};
use super::{ExitReason, FileTransferActivity, Id, Msg, TransferMsg, TransferOpts, UiMsg}; use super::{ExitReason, FileTransferActivity, Id, Msg, TransferMsg, TransferOpts, UiMsg};

File diff suppressed because it is too large Load Diff

View File

@@ -135,7 +135,9 @@ impl SetupActivity {
_ => String::new(), _ => String::new(),
}; };
// Prepare text editor // Prepare text editor
env::set_var("EDITOR", self.config().get_text_editor()); unsafe {
env::set_var("EDITOR", self.config().get_text_editor());
}
let placeholder: String = format!("# Type private SSH key for {username}@{host}\n"); let placeholder: String = format!("# Type private SSH key for {username}@{host}\n");
// Put input mode back to normal // Put input mode back to normal
if let Err(err) = self.context_mut().terminal().disable_raw_mode() { if let Err(err) = self.context_mut().terminal().disable_raw_mode() {

View File

@@ -59,7 +59,9 @@ impl SetupActivity {
None => Ok(()), None => Ok(()),
Some(ctx) => { Some(ctx) => {
// Set editor if config client exists // Set editor if config client exists
env::set_var("EDITOR", ctx.config().get_text_editor()); unsafe {
env::set_var("EDITOR", ctx.config().get_text_editor());
}
// Prepare terminal // Prepare terminal
if let Err(err) = ctx.terminal().disable_raw_mode() { if let Err(err) = ctx.terminal().disable_raw_mode() {
error!("Failed to disable raw mode: {}", err); error!("Failed to disable raw mode: {}", err);

View File

@@ -19,7 +19,7 @@ use tuirealm::listener::EventListenerCfg;
use tuirealm::props::Color; use tuirealm::props::Color;
use tuirealm::{Application, NoUserEvent, Update}; use tuirealm::{Application, NoUserEvent, Update};
use super::{Activity, Context, ExitReason, CROSSTERM_MAX_POLL}; use super::{Activity, CROSSTERM_MAX_POLL, Context, ExitReason};
use crate::config::themes::Theme; use crate::config::themes::Theme;
use crate::system::config_client::ConfigClient; use crate::system::config_client::ConfigClient;
use crate::system::theme_provider::ThemeProvider; use crate::system::theme_provider::ThemeProvider;

View File

@@ -103,10 +103,11 @@ impl SetupActivity {
fn config_update(&mut self, msg: ConfigMsg) -> Option<Msg> { fn config_update(&mut self, msg: ConfigMsg) -> Option<Msg> {
match msg { match msg {
ConfigMsg::CheckUpdatesBlurDown => { ConfigMsg::CheckUpdatesBlurDown => {
assert!(self assert!(
.app self.app
.active(&Id::Config(IdConfig::PromptOnFileReplace)) .active(&Id::Config(IdConfig::PromptOnFileReplace))
.is_ok()); .is_ok()
);
} }
ConfigMsg::CheckUpdatesBlurUp => { ConfigMsg::CheckUpdatesBlurUp => {
assert!(self.app.active(&Id::Config(IdConfig::HiddenFiles)).is_ok()); assert!(self.app.active(&Id::Config(IdConfig::HiddenFiles)).is_ok());
@@ -121,49 +122,55 @@ impl SetupActivity {
assert!(self.app.active(&Id::Config(IdConfig::LocalFileFmt)).is_ok()); assert!(self.app.active(&Id::Config(IdConfig::LocalFileFmt)).is_ok());
} }
ConfigMsg::GroupDirsBlurUp => { ConfigMsg::GroupDirsBlurUp => {
assert!(self assert!(
.app self.app
.active(&Id::Config(IdConfig::PromptOnFileReplace)) .active(&Id::Config(IdConfig::PromptOnFileReplace))
.is_ok()); .is_ok()
);
} }
ConfigMsg::HiddenFilesBlurDown => { ConfigMsg::HiddenFilesBlurDown => {
assert!(self.app.active(&Id::Config(IdConfig::CheckUpdates)).is_ok()); assert!(self.app.active(&Id::Config(IdConfig::CheckUpdates)).is_ok());
} }
ConfigMsg::HiddenFilesBlurUp => { ConfigMsg::HiddenFilesBlurUp => {
assert!(self assert!(
.app self.app
.active(&Id::Config(IdConfig::DefaultProtocol)) .active(&Id::Config(IdConfig::DefaultProtocol))
.is_ok()); .is_ok()
);
} }
ConfigMsg::LocalFileFmtBlurDown => { ConfigMsg::LocalFileFmtBlurDown => {
assert!(self assert!(
.app self.app
.active(&Id::Config(IdConfig::RemoteFileFmt)) .active(&Id::Config(IdConfig::RemoteFileFmt))
.is_ok()); .is_ok()
);
} }
ConfigMsg::LocalFileFmtBlurUp => { ConfigMsg::LocalFileFmtBlurUp => {
assert!(self.app.active(&Id::Config(IdConfig::GroupDirs)).is_ok()); assert!(self.app.active(&Id::Config(IdConfig::GroupDirs)).is_ok());
} }
ConfigMsg::NotificationsEnabledBlurDown => { ConfigMsg::NotificationsEnabledBlurDown => {
assert!(self assert!(
.app self.app
.active(&Id::Config(IdConfig::NotificationsThreshold)) .active(&Id::Config(IdConfig::NotificationsThreshold))
.is_ok()); .is_ok()
);
} }
ConfigMsg::NotificationsEnabledBlurUp => { ConfigMsg::NotificationsEnabledBlurUp => {
assert!(self assert!(
.app self.app
.active(&Id::Config(IdConfig::RemoteFileFmt)) .active(&Id::Config(IdConfig::RemoteFileFmt))
.is_ok()); .is_ok()
);
} }
ConfigMsg::NotificationsThresholdBlurDown => { ConfigMsg::NotificationsThresholdBlurDown => {
assert!(self.app.active(&Id::Config(IdConfig::SshConfig)).is_ok()); assert!(self.app.active(&Id::Config(IdConfig::SshConfig)).is_ok());
} }
ConfigMsg::NotificationsThresholdBlurUp => { ConfigMsg::NotificationsThresholdBlurUp => {
assert!(self assert!(
.app self.app
.active(&Id::Config(IdConfig::NotificationsEnabled)) .active(&Id::Config(IdConfig::NotificationsEnabled))
.is_ok()); .is_ok()
);
} }
ConfigMsg::PromptOnFileReplaceBlurDown => { ConfigMsg::PromptOnFileReplaceBlurDown => {
assert!(self.app.active(&Id::Config(IdConfig::GroupDirs)).is_ok()); assert!(self.app.active(&Id::Config(IdConfig::GroupDirs)).is_ok());
@@ -172,19 +179,21 @@ impl SetupActivity {
assert!(self.app.active(&Id::Config(IdConfig::CheckUpdates)).is_ok()); assert!(self.app.active(&Id::Config(IdConfig::CheckUpdates)).is_ok());
} }
ConfigMsg::RemoteFileFmtBlurDown => { ConfigMsg::RemoteFileFmtBlurDown => {
assert!(self assert!(
.app self.app
.active(&Id::Config(IdConfig::NotificationsEnabled)) .active(&Id::Config(IdConfig::NotificationsEnabled))
.is_ok()); .is_ok()
);
} }
ConfigMsg::RemoteFileFmtBlurUp => { ConfigMsg::RemoteFileFmtBlurUp => {
assert!(self.app.active(&Id::Config(IdConfig::LocalFileFmt)).is_ok()); assert!(self.app.active(&Id::Config(IdConfig::LocalFileFmt)).is_ok());
} }
ConfigMsg::TextEditorBlurDown => { ConfigMsg::TextEditorBlurDown => {
assert!(self assert!(
.app self.app
.active(&Id::Config(IdConfig::DefaultProtocol)) .active(&Id::Config(IdConfig::DefaultProtocol))
.is_ok()); .is_ok()
);
} }
ConfigMsg::TextEditorBlurUp => { ConfigMsg::TextEditorBlurUp => {
assert!(self.app.active(&Id::Config(IdConfig::SshConfig)).is_ok()); assert!(self.app.active(&Id::Config(IdConfig::SshConfig)).is_ok());
@@ -193,10 +202,11 @@ impl SetupActivity {
assert!(self.app.active(&Id::Config(IdConfig::TextEditor)).is_ok()); assert!(self.app.active(&Id::Config(IdConfig::TextEditor)).is_ok());
} }
ConfigMsg::SshConfigBlurUp => { ConfigMsg::SshConfigBlurUp => {
assert!(self assert!(
.app self.app
.active(&Id::Config(IdConfig::NotificationsThreshold)) .active(&Id::Config(IdConfig::NotificationsThreshold))
.is_ok()); .is_ok()
);
} }
ConfigMsg::ConfigChanged => { ConfigMsg::ConfigChanged => {
self.set_config_changed(true); self.set_config_changed(true);
@@ -259,10 +269,11 @@ impl SetupActivity {
assert!(self.app.active(&Id::Theme(IdTheme::AuthProtocol)).is_ok()); assert!(self.app.active(&Id::Theme(IdTheme::AuthProtocol)).is_ok());
} }
ThemeMsg::AuthBookmarksBlurDown => { ThemeMsg::AuthBookmarksBlurDown => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::AuthRecentHosts)) .active(&Id::Theme(IdTheme::AuthRecentHosts))
.is_ok()); .is_ok()
);
} }
ThemeMsg::AuthBookmarksBlurUp => { ThemeMsg::AuthBookmarksBlurUp => {
assert!(self.app.active(&Id::Theme(IdTheme::AuthPassword)).is_ok()); assert!(self.app.active(&Id::Theme(IdTheme::AuthPassword)).is_ok());
@@ -301,10 +312,11 @@ impl SetupActivity {
assert!(self.app.active(&Id::Theme(IdTheme::MiscInfo)).is_ok()); assert!(self.app.active(&Id::Theme(IdTheme::MiscInfo)).is_ok());
} }
ThemeMsg::MiscErrorBlurUp => { ThemeMsg::MiscErrorBlurUp => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::AuthRecentHosts)) .active(&Id::Theme(IdTheme::AuthRecentHosts))
.is_ok()); .is_ok()
);
} }
ThemeMsg::MiscInfoBlurDown => { ThemeMsg::MiscInfoBlurDown => {
assert!(self.app.active(&Id::Theme(IdTheme::MiscInput)).is_ok()); assert!(self.app.active(&Id::Theme(IdTheme::MiscInput)).is_ok());
@@ -337,88 +349,100 @@ impl SetupActivity {
assert!(self.app.active(&Id::Theme(IdTheme::MiscQuit)).is_ok()); assert!(self.app.active(&Id::Theme(IdTheme::MiscQuit)).is_ok());
} }
ThemeMsg::MiscWarnBlurDown => { ThemeMsg::MiscWarnBlurDown => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::ExplorerLocalBg)) .active(&Id::Theme(IdTheme::ExplorerLocalBg))
.is_ok()); .is_ok()
);
} }
ThemeMsg::MiscWarnBlurUp => { ThemeMsg::MiscWarnBlurUp => {
assert!(self.app.active(&Id::Theme(IdTheme::MiscSave)).is_ok()); assert!(self.app.active(&Id::Theme(IdTheme::MiscSave)).is_ok());
} }
ThemeMsg::ExplorerLocalBgBlurDown => { ThemeMsg::ExplorerLocalBgBlurDown => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::ExplorerLocalFg)) .active(&Id::Theme(IdTheme::ExplorerLocalFg))
.is_ok()); .is_ok()
);
} }
ThemeMsg::ExplorerLocalBgBlurUp => { ThemeMsg::ExplorerLocalBgBlurUp => {
assert!(self.app.active(&Id::Theme(IdTheme::MiscWarn)).is_ok()); assert!(self.app.active(&Id::Theme(IdTheme::MiscWarn)).is_ok());
} }
ThemeMsg::ExplorerLocalFgBlurDown => { ThemeMsg::ExplorerLocalFgBlurDown => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::ExplorerLocalHg)) .active(&Id::Theme(IdTheme::ExplorerLocalHg))
.is_ok()); .is_ok()
);
} }
ThemeMsg::ExplorerLocalFgBlurUp => { ThemeMsg::ExplorerLocalFgBlurUp => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::ExplorerLocalBg)) .active(&Id::Theme(IdTheme::ExplorerLocalBg))
.is_ok()); .is_ok()
);
} }
ThemeMsg::ExplorerLocalHgBlurDown => { ThemeMsg::ExplorerLocalHgBlurDown => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::ExplorerRemoteBg)) .active(&Id::Theme(IdTheme::ExplorerRemoteBg))
.is_ok()); .is_ok()
);
} }
ThemeMsg::ExplorerLocalHgBlurUp => { ThemeMsg::ExplorerLocalHgBlurUp => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::ExplorerLocalFg)) .active(&Id::Theme(IdTheme::ExplorerLocalFg))
.is_ok()); .is_ok()
);
} }
ThemeMsg::ExplorerRemoteBgBlurDown => { ThemeMsg::ExplorerRemoteBgBlurDown => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::ExplorerRemoteFg)) .active(&Id::Theme(IdTheme::ExplorerRemoteFg))
.is_ok()); .is_ok()
);
} }
ThemeMsg::ExplorerRemoteBgBlurUp => { ThemeMsg::ExplorerRemoteBgBlurUp => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::ExplorerLocalHg)) .active(&Id::Theme(IdTheme::ExplorerLocalHg))
.is_ok()); .is_ok()
);
} }
ThemeMsg::ExplorerRemoteFgBlurDown => { ThemeMsg::ExplorerRemoteFgBlurDown => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::ExplorerRemoteHg)) .active(&Id::Theme(IdTheme::ExplorerRemoteHg))
.is_ok()); .is_ok()
);
} }
ThemeMsg::ExplorerRemoteFgBlurUp => { ThemeMsg::ExplorerRemoteFgBlurUp => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::ExplorerRemoteBg)) .active(&Id::Theme(IdTheme::ExplorerRemoteBg))
.is_ok()); .is_ok()
);
} }
ThemeMsg::ExplorerRemoteHgBlurDown => { ThemeMsg::ExplorerRemoteHgBlurDown => {
assert!(self.app.active(&Id::Theme(IdTheme::ProgBarFull)).is_ok()); assert!(self.app.active(&Id::Theme(IdTheme::ProgBarFull)).is_ok());
} }
ThemeMsg::ExplorerRemoteHgBlurUp => { ThemeMsg::ExplorerRemoteHgBlurUp => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::ExplorerRemoteFg)) .active(&Id::Theme(IdTheme::ExplorerRemoteFg))
.is_ok()); .is_ok()
);
} }
ThemeMsg::ProgBarFullBlurDown => { ThemeMsg::ProgBarFullBlurDown => {
assert!(self.app.active(&Id::Theme(IdTheme::ProgBarPartial)).is_ok()); assert!(self.app.active(&Id::Theme(IdTheme::ProgBarPartial)).is_ok());
} }
ThemeMsg::ProgBarFullBlurUp => { ThemeMsg::ProgBarFullBlurUp => {
assert!(self assert!(
.app self.app
.active(&Id::Theme(IdTheme::ExplorerRemoteHg)) .active(&Id::Theme(IdTheme::ExplorerRemoteHg))
.is_ok()); .is_ok()
);
} }
ThemeMsg::ProgBarPartialBlurDown => { ThemeMsg::ProgBarPartialBlurDown => {
assert!(self.app.active(&Id::Theme(IdTheme::LogBg)).is_ok()); assert!(self.app.active(&Id::Theme(IdTheme::LogBg)).is_ok());

View File

@@ -40,14 +40,15 @@ impl SetupActivity {
/// Mount error box /// Mount error box
pub(super) fn mount_error<S: AsRef<str>>(&mut self, text: S) { pub(super) fn mount_error<S: AsRef<str>>(&mut self, text: S) {
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Common(IdCommon::ErrorPopup), Id::Common(IdCommon::ErrorPopup),
Box::new(components::ErrorPopup::new(text)), Box::new(components::ErrorPopup::new(text)),
vec![], vec![],
) )
.is_ok()); .is_ok()
);
assert!(self.app.active(&Id::Common(IdCommon::ErrorPopup)).is_ok()); assert!(self.app.active(&Id::Common(IdCommon::ErrorPopup)).is_ok());
} }
@@ -58,14 +59,15 @@ impl SetupActivity {
/// Mount quit popup /// Mount quit popup
pub(super) fn mount_quit(&mut self) { pub(super) fn mount_quit(&mut self) {
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Common(IdCommon::QuitPopup), Id::Common(IdCommon::QuitPopup),
Box::<components::QuitPopup>::default(), Box::<components::QuitPopup>::default(),
vec![], vec![],
) )
.is_ok()); .is_ok()
);
assert!(self.app.active(&Id::Common(IdCommon::QuitPopup)).is_ok()); assert!(self.app.active(&Id::Common(IdCommon::QuitPopup)).is_ok());
} }
@@ -76,14 +78,15 @@ impl SetupActivity {
/// Mount save popup /// Mount save popup
pub(super) fn mount_save_popup(&mut self) { pub(super) fn mount_save_popup(&mut self) {
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Common(IdCommon::SavePopup), Id::Common(IdCommon::SavePopup),
Box::<components::SavePopup>::default(), Box::<components::SavePopup>::default(),
vec![], vec![],
) )
.is_ok()); .is_ok()
);
assert!(self.app.active(&Id::Common(IdCommon::SavePopup)).is_ok()); assert!(self.app.active(&Id::Common(IdCommon::SavePopup)).is_ok());
} }
@@ -94,14 +97,15 @@ impl SetupActivity {
/// Mount help /// Mount help
pub(super) fn mount_help(&mut self) { pub(super) fn mount_help(&mut self) {
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Common(IdCommon::Keybindings), Id::Common(IdCommon::Keybindings),
Box::<components::Keybindings>::default(), Box::<components::Keybindings>::default(),
vec![], vec![],
) )
.is_ok()); .is_ok()
);
assert!(self.app.active(&Id::Common(IdCommon::Keybindings)).is_ok()); assert!(self.app.active(&Id::Common(IdCommon::Keybindings)).is_ok());
} }
@@ -144,93 +148,96 @@ impl SetupActivity {
/// Mount common components /// Mount common components
fn mount_commons(&mut self, layout: ViewLayout) { fn mount_commons(&mut self, layout: ViewLayout) {
// Radio tab // Radio tab
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Common(IdCommon::Header), Id::Common(IdCommon::Header),
Box::new(components::Header::new(layout)), Box::new(components::Header::new(layout)),
vec![], vec![],
) )
.is_ok()); .is_ok()
);
// Footer // Footer
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Common(IdCommon::Footer), Id::Common(IdCommon::Footer),
Box::<components::Footer>::default(), Box::<components::Footer>::default(),
vec![], vec![],
) )
.is_ok()); .is_ok()
);
} }
/// Mount global listener /// Mount global listener
fn mount_global_listener(&mut self) { fn mount_global_listener(&mut self) {
assert!(self assert!(
.app self.app
.mount( .mount(
Id::Common(IdCommon::GlobalListener), Id::Common(IdCommon::GlobalListener),
Box::<components::GlobalListener>::default(), Box::<components::GlobalListener>::default(),
vec![ vec![
Sub::new( Sub::new(
SubEventClause::Keyboard(KeyEvent { SubEventClause::Keyboard(KeyEvent {
code: Key::Esc, code: Key::Esc,
modifiers: KeyModifiers::NONE, modifiers: KeyModifiers::NONE,
}), }),
Self::no_popup_mounted_clause(), Self::no_popup_mounted_clause(),
), ),
Sub::new( Sub::new(
SubEventClause::Keyboard(KeyEvent { SubEventClause::Keyboard(KeyEvent {
code: Key::Function(10), code: Key::Function(10),
modifiers: KeyModifiers::NONE, modifiers: KeyModifiers::NONE,
}), }),
Self::no_popup_mounted_clause(), Self::no_popup_mounted_clause(),
), ),
Sub::new( Sub::new(
SubEventClause::Keyboard(KeyEvent { SubEventClause::Keyboard(KeyEvent {
code: Key::Tab, code: Key::Tab,
modifiers: KeyModifiers::NONE, modifiers: KeyModifiers::NONE,
}), }),
Self::no_popup_mounted_clause(), Self::no_popup_mounted_clause(),
), ),
Sub::new( Sub::new(
SubEventClause::Keyboard(KeyEvent { SubEventClause::Keyboard(KeyEvent {
code: Key::Char('h'), code: Key::Char('h'),
modifiers: KeyModifiers::CONTROL, modifiers: KeyModifiers::CONTROL,
}), }),
Self::no_popup_mounted_clause(), Self::no_popup_mounted_clause(),
), ),
Sub::new( Sub::new(
SubEventClause::Keyboard(KeyEvent { SubEventClause::Keyboard(KeyEvent {
code: Key::Function(1), code: Key::Function(1),
modifiers: KeyModifiers::NONE, modifiers: KeyModifiers::NONE,
}), }),
Self::no_popup_mounted_clause(), Self::no_popup_mounted_clause(),
), ),
Sub::new( Sub::new(
SubEventClause::Keyboard(KeyEvent { SubEventClause::Keyboard(KeyEvent {
code: Key::Char('r'), code: Key::Char('r'),
modifiers: KeyModifiers::CONTROL, modifiers: KeyModifiers::CONTROL,
}), }),
Self::no_popup_mounted_clause(), Self::no_popup_mounted_clause(),
), ),
Sub::new( Sub::new(
SubEventClause::Keyboard(KeyEvent { SubEventClause::Keyboard(KeyEvent {
code: Key::Char('s'), code: Key::Char('s'),
modifiers: KeyModifiers::CONTROL, modifiers: KeyModifiers::CONTROL,
}), }),
Self::no_popup_mounted_clause(), Self::no_popup_mounted_clause(),
), ),
Sub::new( Sub::new(
SubEventClause::Keyboard(KeyEvent { SubEventClause::Keyboard(KeyEvent {
code: Key::Function(4), code: Key::Function(4),
modifiers: KeyModifiers::NONE, modifiers: KeyModifiers::NONE,
}), }),
Self::no_popup_mounted_clause(), Self::no_popup_mounted_clause(),
), ),
Sub::new(SubEventClause::WindowResize, SubClause::Always) Sub::new(SubEventClause::WindowResize, SubClause::Always)
] ]
) )
.is_ok()); .is_ok()
);
} }
/// Returns a sub clause which requires that no popup is mounted in order to be satisfied /// Returns a sub clause which requires that no popup is mounted in order to be satisfied

View File

@@ -11,8 +11,8 @@ use tuirealm::ratatui::layout::{Constraint, Direction, Layout};
use tuirealm::{State, StateValue}; use tuirealm::{State, StateValue};
use super::{ use super::{
components, Context, Id, IdCommon, IdConfig, SetupActivity, ViewLayout, RADIO_PROTOCOL_KUBE, Context, Id, IdCommon, IdConfig, RADIO_PROTOCOL_KUBE, RADIO_PROTOCOL_WEBDAV, SetupActivity,
RADIO_PROTOCOL_WEBDAV, ViewLayout, components,
}; };
use crate::explorer::GroupDirs; use crate::explorer::GroupDirs;
use crate::filetransfer::FileTransferProtocol; use crate::filetransfer::FileTransferProtocol;
@@ -145,122 +145,133 @@ impl SetupActivity {
// Text editor // Text editor
let text_editor: String = let text_editor: String =
String::from(self.config().get_text_editor().as_path().to_string_lossy()); String::from(self.config().get_text_editor().as_path().to_string_lossy());
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Config(IdConfig::TextEditor), Id::Config(IdConfig::TextEditor),
Box::new(components::TextEditor::new(text_editor.as_str())), Box::new(components::TextEditor::new(text_editor.as_str())),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
// Protocol // Protocol
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Config(IdConfig::DefaultProtocol), Id::Config(IdConfig::DefaultProtocol),
Box::new(components::DefaultProtocol::new( Box::new(components::DefaultProtocol::new(
self.config().get_default_protocol() self.config().get_default_protocol()
)), )),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
// Hidden files // Hidden files
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Config(IdConfig::HiddenFiles), Id::Config(IdConfig::HiddenFiles),
Box::new(components::HiddenFiles::new( Box::new(components::HiddenFiles::new(
self.config().get_show_hidden_files() self.config().get_show_hidden_files()
)), )),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
// Updates // Updates
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Config(IdConfig::CheckUpdates), Id::Config(IdConfig::CheckUpdates),
Box::new(components::CheckUpdates::new( Box::new(components::CheckUpdates::new(
self.config().get_check_for_updates() self.config().get_check_for_updates()
)), )),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
// File replace // File replace
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Config(IdConfig::PromptOnFileReplace), Id::Config(IdConfig::PromptOnFileReplace),
Box::new(components::PromptOnFileReplace::new( Box::new(components::PromptOnFileReplace::new(
self.config().get_prompt_on_file_replace() self.config().get_prompt_on_file_replace()
)), )),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
// Group dirs // Group dirs
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Config(IdConfig::GroupDirs), Id::Config(IdConfig::GroupDirs),
Box::new(components::GroupDirs::new(self.config().get_group_dirs())), Box::new(components::GroupDirs::new(self.config().get_group_dirs())),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
// Local File Fmt // Local File Fmt
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Config(IdConfig::LocalFileFmt), Id::Config(IdConfig::LocalFileFmt),
Box::new(components::LocalFileFmt::new( Box::new(components::LocalFileFmt::new(
&self.config().get_local_file_fmt().unwrap_or_default() &self.config().get_local_file_fmt().unwrap_or_default()
)), )),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
// Remote File Fmt // Remote File Fmt
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Config(IdConfig::RemoteFileFmt), Id::Config(IdConfig::RemoteFileFmt),
Box::new(components::RemoteFileFmt::new( Box::new(components::RemoteFileFmt::new(
&self.config().get_remote_file_fmt().unwrap_or_default() &self.config().get_remote_file_fmt().unwrap_or_default()
)), )),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
// Notifications enabled // Notifications enabled
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Config(IdConfig::NotificationsEnabled), Id::Config(IdConfig::NotificationsEnabled),
Box::new(components::NotificationsEnabled::new( Box::new(components::NotificationsEnabled::new(
self.config().get_notifications() self.config().get_notifications()
)), )),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
// Notifications threshold // Notifications threshold
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Config(IdConfig::NotificationsThreshold), Id::Config(IdConfig::NotificationsThreshold),
Box::new(components::NotificationsThreshold::new(&fmt_bytes( Box::new(components::NotificationsThreshold::new(&fmt_bytes(
self.config().get_notification_threshold() self.config().get_notification_threshold()
))), ))),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
// Ssh config // Ssh config
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Config(IdConfig::SshConfig), Id::Config(IdConfig::SshConfig),
Box::new(components::SshConfig::new( Box::new(components::SshConfig::new(
self.config().get_ssh_config().unwrap_or("") self.config().get_ssh_config().unwrap_or("")
)), )),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
} }
/// Collect values from input and put them into the configuration /// Collect values from input and put them into the configuration

View File

@@ -8,7 +8,7 @@
use tuirealm::ratatui::layout::{Constraint, Direction, Layout}; use tuirealm::ratatui::layout::{Constraint, Direction, Layout};
use tuirealm::ratatui::widgets::Clear; use tuirealm::ratatui::widgets::Clear;
use super::{components, Context, Id, IdCommon, IdSsh, SetupActivity, ViewLayout}; use super::{Context, Id, IdCommon, IdSsh, SetupActivity, ViewLayout, components};
use crate::utils::ui::{Popup, Size}; use crate::utils::ui::{Popup, Size};
impl SetupActivity { impl SetupActivity {
@@ -74,14 +74,15 @@ impl SetupActivity {
/// Mount delete ssh key component /// Mount delete ssh key component
pub(crate) fn mount_del_ssh_key(&mut self) { pub(crate) fn mount_del_ssh_key(&mut self) {
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Ssh(IdSsh::DelSshKeyPopup), Id::Ssh(IdSsh::DelSshKeyPopup),
Box::<components::DelSshKeyPopup>::default(), Box::<components::DelSshKeyPopup>::default(),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
assert!(self.app.active(&Id::Ssh(IdSsh::DelSshKeyPopup)).is_ok()); assert!(self.app.active(&Id::Ssh(IdSsh::DelSshKeyPopup)).is_ok());
} }
@@ -92,22 +93,24 @@ impl SetupActivity {
/// Mount new ssh key prompt /// Mount new ssh key prompt
pub(crate) fn mount_new_ssh_key(&mut self) { pub(crate) fn mount_new_ssh_key(&mut self) {
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Ssh(IdSsh::SshHost), Id::Ssh(IdSsh::SshHost),
Box::<components::SshHost>::default(), Box::<components::SshHost>::default(),
vec![] vec![]
) )
.is_ok()); .is_ok()
assert!(self );
.app assert!(
.remount( self.app
Id::Ssh(IdSsh::SshUsername), .remount(
Box::<components::SshUsername>::default(), Id::Ssh(IdSsh::SshUsername),
vec![] Box::<components::SshUsername>::default(),
) vec![]
.is_ok()); )
.is_ok()
);
assert!(self.app.active(&Id::Ssh(IdSsh::SshHost)).is_ok()); assert!(self.app.active(&Id::Ssh(IdSsh::SshHost)).is_ok());
} }
@@ -127,14 +130,15 @@ impl SetupActivity {
format!("{username} at {addr}") format!("{username} at {addr}")
}) })
.collect(); .collect();
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Ssh(IdSsh::SshKeys), Id::Ssh(IdSsh::SshKeys),
Box::new(components::SshKeys::new(&keys)), Box::new(components::SshKeys::new(&keys)),
vec![] vec![]
) )
.is_ok()); .is_ok()
);
assert!(self.app.active(&Id::Ssh(IdSsh::SshKeys)).is_ok()); assert!(self.app.active(&Id::Ssh(IdSsh::SshKeys)).is_ok());
} }
} }

View File

@@ -7,7 +7,7 @@
// Ext // Ext
use tuirealm::ratatui::layout::{Constraint, Direction, Layout}; use tuirealm::ratatui::layout::{Constraint, Direction, Layout};
use super::{components, Context, Id, IdCommon, IdTheme, SetupActivity, Theme, ViewLayout}; use super::{Context, Id, IdCommon, IdTheme, SetupActivity, Theme, ViewLayout, components};
impl SetupActivity { impl SetupActivity {
// -- view // -- view
@@ -242,278 +242,309 @@ impl SetupActivity {
} }
fn load_titles(&mut self) { fn load_titles(&mut self) {
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Theme(IdTheme::AuthTitle), Id::Theme(IdTheme::AuthTitle),
Box::<components::AuthTitle>::default(), Box::<components::AuthTitle>::default(),
vec![] vec![]
) )
.is_ok()); .is_ok()
assert!(self );
.app assert!(
.remount( self.app
Id::Theme(IdTheme::MiscTitle), .remount(
Box::<components::MiscTitle>::default(), Id::Theme(IdTheme::MiscTitle),
vec![] Box::<components::MiscTitle>::default(),
) vec![]
.is_ok()); )
assert!(self .is_ok()
.app );
.remount( assert!(
Id::Theme(IdTheme::TransferTitle), self.app
Box::<components::TransferTitle>::default(), .remount(
vec![] Id::Theme(IdTheme::TransferTitle),
) Box::<components::TransferTitle>::default(),
.is_ok()); vec![]
assert!(self )
.app .is_ok()
.remount( );
Id::Theme(IdTheme::TransferTitle2), assert!(
Box::<components::TransferTitle2>::default(), self.app
vec![] .remount(
) Id::Theme(IdTheme::TransferTitle2),
.is_ok()); Box::<components::TransferTitle2>::default(),
vec![]
)
.is_ok()
);
} }
/// Load values from theme into input fields /// Load values from theme into input fields
pub(crate) fn load_styles(&mut self) { pub(crate) fn load_styles(&mut self) {
let theme: Theme = self.theme().clone(); let theme: Theme = self.theme().clone();
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Theme(IdTheme::AuthAddress), Id::Theme(IdTheme::AuthAddress),
Box::new(components::AuthAddress::new(theme.auth_address)), Box::new(components::AuthAddress::new(theme.auth_address)),
vec![] vec![]
) )
.is_ok()); .is_ok()
assert!(self );
.app assert!(
.remount( self.app
Id::Theme(IdTheme::AuthBookmarks), .remount(
Box::new(components::AuthBookmarks::new(theme.auth_bookmarks)), Id::Theme(IdTheme::AuthBookmarks),
vec![] Box::new(components::AuthBookmarks::new(theme.auth_bookmarks)),
) vec![]
.is_ok()); )
assert!(self .is_ok()
.app );
.remount( assert!(
Id::Theme(IdTheme::AuthPassword), self.app
Box::new(components::AuthPassword::new(theme.auth_password)), .remount(
vec![] Id::Theme(IdTheme::AuthPassword),
) Box::new(components::AuthPassword::new(theme.auth_password)),
.is_ok()); vec![]
assert!(self )
.app .is_ok()
.remount( );
Id::Theme(IdTheme::AuthPort), assert!(
Box::new(components::AuthPort::new(theme.auth_port)), self.app
vec![] .remount(
) Id::Theme(IdTheme::AuthPort),
.is_ok()); Box::new(components::AuthPort::new(theme.auth_port)),
assert!(self vec![]
.app )
.remount( .is_ok()
Id::Theme(IdTheme::AuthProtocol), );
Box::new(components::AuthProtocol::new(theme.auth_protocol)), assert!(
vec![] self.app
) .remount(
.is_ok()); Id::Theme(IdTheme::AuthProtocol),
assert!(self Box::new(components::AuthProtocol::new(theme.auth_protocol)),
.app vec![]
.remount( )
Id::Theme(IdTheme::AuthRecentHosts), .is_ok()
Box::new(components::AuthRecentHosts::new(theme.auth_recents)), );
vec![] assert!(
) self.app
.is_ok()); .remount(
assert!(self Id::Theme(IdTheme::AuthRecentHosts),
.app Box::new(components::AuthRecentHosts::new(theme.auth_recents)),
.remount( vec![]
Id::Theme(IdTheme::AuthUsername), )
Box::new(components::AuthUsername::new(theme.auth_username)), .is_ok()
vec![] );
) assert!(
.is_ok()); self.app
assert!(self .remount(
.app Id::Theme(IdTheme::AuthUsername),
.remount( Box::new(components::AuthUsername::new(theme.auth_username)),
Id::Theme(IdTheme::MiscError), vec![]
Box::new(components::MiscError::new(theme.misc_error_dialog)), )
vec![] .is_ok()
) );
.is_ok()); assert!(
assert!(self self.app
.app .remount(
.remount( Id::Theme(IdTheme::MiscError),
Id::Theme(IdTheme::MiscInfo), Box::new(components::MiscError::new(theme.misc_error_dialog)),
Box::new(components::MiscInfo::new(theme.misc_info_dialog)), vec![]
vec![] )
) .is_ok()
.is_ok()); );
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Theme(IdTheme::MiscInput), Id::Theme(IdTheme::MiscInfo),
Box::new(components::MiscInput::new(theme.misc_input_dialog)), Box::new(components::MiscInfo::new(theme.misc_info_dialog)),
vec![] vec![]
) )
.is_ok()); .is_ok()
assert!(self );
.app assert!(
.remount( self.app
Id::Theme(IdTheme::MiscKeys), .remount(
Box::new(components::MiscKeys::new(theme.misc_keys)), Id::Theme(IdTheme::MiscInput),
vec![] Box::new(components::MiscInput::new(theme.misc_input_dialog)),
) vec![]
.is_ok()); )
assert!(self .is_ok()
.app );
.remount( assert!(
Id::Theme(IdTheme::MiscQuit), self.app
Box::new(components::MiscQuit::new(theme.misc_quit_dialog)), .remount(
vec![] Id::Theme(IdTheme::MiscKeys),
) Box::new(components::MiscKeys::new(theme.misc_keys)),
.is_ok()); vec![]
assert!(self )
.app .is_ok()
.remount( );
Id::Theme(IdTheme::MiscSave), assert!(
Box::new(components::MiscSave::new(theme.misc_save_dialog)), self.app
vec![] .remount(
) Id::Theme(IdTheme::MiscQuit),
.is_ok()); Box::new(components::MiscQuit::new(theme.misc_quit_dialog)),
assert!(self vec![]
.app )
.remount( .is_ok()
Id::Theme(IdTheme::MiscWarn), );
Box::new(components::MiscWarn::new(theme.misc_warn_dialog)), assert!(
vec![] self.app
) .remount(
.is_ok()); Id::Theme(IdTheme::MiscSave),
assert!(self Box::new(components::MiscSave::new(theme.misc_save_dialog)),
.app vec![]
.remount( )
Id::Theme(IdTheme::ExplorerLocalBg), .is_ok()
Box::new(components::ExplorerLocalBg::new( );
theme.transfer_local_explorer_background assert!(
)), self.app
vec![] .remount(
) Id::Theme(IdTheme::MiscWarn),
.is_ok()); Box::new(components::MiscWarn::new(theme.misc_warn_dialog)),
assert!(self vec![]
.app )
.remount( .is_ok()
Id::Theme(IdTheme::ExplorerLocalFg), );
Box::new(components::ExplorerLocalFg::new( assert!(
theme.transfer_local_explorer_foreground self.app
)), .remount(
vec![] Id::Theme(IdTheme::ExplorerLocalBg),
) Box::new(components::ExplorerLocalBg::new(
.is_ok()); theme.transfer_local_explorer_background
assert!(self )),
.app vec![]
.remount( )
Id::Theme(IdTheme::ExplorerLocalHg), .is_ok()
Box::new(components::ExplorerLocalHg::new( );
theme.transfer_local_explorer_highlighted assert!(
)), self.app
vec![] .remount(
) Id::Theme(IdTheme::ExplorerLocalFg),
.is_ok()); Box::new(components::ExplorerLocalFg::new(
assert!(self theme.transfer_local_explorer_foreground
.app )),
.remount( vec![]
Id::Theme(IdTheme::ExplorerRemoteBg), )
Box::new(components::ExplorerRemoteBg::new( .is_ok()
theme.transfer_remote_explorer_background );
)), assert!(
vec![] self.app
) .remount(
.is_ok()); Id::Theme(IdTheme::ExplorerLocalHg),
assert!(self Box::new(components::ExplorerLocalHg::new(
.app theme.transfer_local_explorer_highlighted
.remount( )),
Id::Theme(IdTheme::ExplorerRemoteFg), vec![]
Box::new(components::ExplorerRemoteFg::new( )
theme.transfer_remote_explorer_foreground .is_ok()
)), );
vec![] assert!(
) self.app
.is_ok()); .remount(
assert!(self Id::Theme(IdTheme::ExplorerRemoteBg),
.app Box::new(components::ExplorerRemoteBg::new(
.remount( theme.transfer_remote_explorer_background
Id::Theme(IdTheme::ExplorerRemoteHg), )),
Box::new(components::ExplorerRemoteHg::new( vec![]
theme.transfer_remote_explorer_highlighted )
)), .is_ok()
vec![] );
) assert!(
.is_ok()); self.app
assert!(self .remount(
.app Id::Theme(IdTheme::ExplorerRemoteFg),
.remount( Box::new(components::ExplorerRemoteFg::new(
Id::Theme(IdTheme::ProgBarFull), theme.transfer_remote_explorer_foreground
Box::new(components::ProgBarFull::new( )),
theme.transfer_progress_bar_full vec![]
)), )
vec![] .is_ok()
) );
.is_ok()); assert!(
assert!(self self.app
.app .remount(
.remount( Id::Theme(IdTheme::ExplorerRemoteHg),
Id::Theme(IdTheme::ProgBarPartial), Box::new(components::ExplorerRemoteHg::new(
Box::new(components::ProgBarPartial::new( theme.transfer_remote_explorer_highlighted
theme.transfer_progress_bar_partial )),
)), vec![]
vec![] )
) .is_ok()
.is_ok()); );
assert!(self assert!(
.app self.app
.remount( .remount(
Id::Theme(IdTheme::LogBg), Id::Theme(IdTheme::ProgBarFull),
Box::new(components::LogBg::new(theme.transfer_log_background)), Box::new(components::ProgBarFull::new(
vec![] theme.transfer_progress_bar_full
) )),
.is_ok()); vec![]
assert!(self )
.app .is_ok()
.remount( );
Id::Theme(IdTheme::LogWindow), assert!(
Box::new(components::LogWindow::new(theme.transfer_log_window)), self.app
vec![] .remount(
) Id::Theme(IdTheme::ProgBarPartial),
.is_ok()); Box::new(components::ProgBarPartial::new(
assert!(self theme.transfer_progress_bar_partial
.app )),
.remount( vec![]
Id::Theme(IdTheme::StatusSorting), )
Box::new(components::StatusSorting::new( .is_ok()
theme.transfer_status_sorting );
)), assert!(
vec![] self.app
) .remount(
.is_ok()); Id::Theme(IdTheme::LogBg),
assert!(self Box::new(components::LogBg::new(theme.transfer_log_background)),
.app vec![]
.remount( )
Id::Theme(IdTheme::StatusHidden), .is_ok()
Box::new(components::StatusHidden::new(theme.transfer_status_hidden)), );
vec![] assert!(
) self.app
.is_ok()); .remount(
assert!(self Id::Theme(IdTheme::LogWindow),
.app Box::new(components::LogWindow::new(theme.transfer_log_window)),
.remount( vec![]
Id::Theme(IdTheme::StatusSync), )
Box::new(components::StatusSync::new( .is_ok()
theme.transfer_status_sync_browsing );
)), assert!(
vec![] self.app
) .remount(
.is_ok()); Id::Theme(IdTheme::StatusSorting),
Box::new(components::StatusSorting::new(
theme.transfer_status_sorting
)),
vec![]
)
.is_ok()
);
assert!(
self.app
.remount(
Id::Theme(IdTheme::StatusHidden),
Box::new(components::StatusHidden::new(theme.transfer_status_hidden)),
vec![]
)
.is_ok()
);
assert!(
self.app
.remount(
Id::Theme(IdTheme::StatusSync),
Box::new(components::StatusSync::new(
theme.transfer_status_sync_browsing
)),
vec![]
)
.is_ok()
);
} }
} }

View File

@@ -3,12 +3,13 @@
//! `random` is the module which provides utilities for rand //! `random` is the module which provides utilities for rand
// Ext // Ext
use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng}; use rand::distr::Alphanumeric;
use rand::{Rng, rng};
/// Generate a random alphanumeric string with provided length /// Generate a random alphanumeric string with provided length
pub fn random_alphanumeric_with_len(len: usize) -> String { pub fn random_alphanumeric_with_len(len: usize) -> String {
let mut rng = thread_rng(); let mut rng = rng();
std::iter::repeat(()) std::iter::repeat(())
.map(|()| rng.sample(Alphanumeric)) .map(|()| rng.sample(Alphanumeric))
.map(char::from) .map(char::from)

View File

@@ -20,7 +20,9 @@ mod test {
#[test] #[test]
fn should_parse_ssh2_config() { fn should_parse_ssh2_config() {
let rsa_key = test_helpers::create_sample_file_with_content("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDErJhQxEI0+VvhlXVUyh+vMCm7aXfCA/g633AG8ezD/5EylwchtAr2JCoBWnxn4zV8nI9dMqOgm0jO4IsXpKOjQojv+0VOH7I+cDlBg0tk4hFlvyyS6YviDAfDDln3jYUM+5QNDfQLaZlH2WvcJ3mkDxLVlI9MBX1BAeSmChLxwAvxALp2ncImNQLzDO9eHcig3dtMrEKkzXQowRW5Y7eUzg2+vvVq4H2DOjWwUndvB5sJkhEfTUVE7ID8ZdGJo60kUb/02dZYj+IbkAnMCsqktk0cg/4XFX82hEfRYFeb1arkysFisPU1DOb6QielL/axeTebVplaouYcXY0pFdJt root@8c50fd4c345a"); let rsa_key = test_helpers::create_sample_file_with_content(
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDErJhQxEI0+VvhlXVUyh+vMCm7aXfCA/g633AG8ezD/5EylwchtAr2JCoBWnxn4zV8nI9dMqOgm0jO4IsXpKOjQojv+0VOH7I+cDlBg0tk4hFlvyyS6YviDAfDDln3jYUM+5QNDfQLaZlH2WvcJ3mkDxLVlI9MBX1BAeSmChLxwAvxALp2ncImNQLzDO9eHcig3dtMrEKkzXQowRW5Y7eUzg2+vvVq4H2DOjWwUndvB5sJkhEfTUVE7ID8ZdGJo60kUb/02dZYj+IbkAnMCsqktk0cg/4XFX82hEfRYFeb1arkysFisPU1DOb6QielL/axeTebVplaouYcXY0pFdJt root@8c50fd4c345a",
);
let ssh_config_file = test_helpers::create_sample_file_with_content(format!( let ssh_config_file = test_helpers::create_sample_file_with_content(format!(
r#" r#"
Host test Host test
@@ -34,13 +36,15 @@ Host test
rsa_key.path().display() rsa_key.path().display()
)); ));
assert!(parse_ssh2_config( assert!(
ssh_config_file parse_ssh2_config(
.path() ssh_config_file
.to_string_lossy() .path()
.to_string() .to_string_lossy()
.as_str() .to_string()
) .as_str()
.is_ok()); )
.is_ok()
);
} }
} }

View File

@@ -24,7 +24,9 @@ pub fn create_sample_file_entry() -> (File, NamedTempFile) {
/// Create sample file with default lorem ipsum content /// Create sample file with default lorem ipsum content
pub fn create_sample_file() -> NamedTempFile { pub fn create_sample_file() -> NamedTempFile {
create_sample_file_with_content("Lorem ipsum dolor sit amet, consectetur adipiscing elit.Mauris ultricies consequat eros,nec scelerisque magna imperdiet metus.") create_sample_file_with_content(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.Mauris ultricies consequat eros,nec scelerisque magna imperdiet metus.",
)
} }
/// Create sample file with provided content /// Create sample file with provided content

View File

@@ -65,9 +65,9 @@ mod tests {
fn test_utils_ui_draw_area_in() { fn test_utils_ui_draw_area_in() {
let area: Rect = Rect::new(0, 0, 1024, 512); let area: Rect = Rect::new(0, 0, 1024, 512);
let child: Rect = Popup(Size::Percentage(75), Size::Percentage(30)).draw_in(area); let child: Rect = Popup(Size::Percentage(75), Size::Percentage(30)).draw_in(area);
assert_eq!(child.x, 43); assert_eq!(child.x, 123);
assert_eq!(child.y, 63); assert_eq!(child.y, 179);
assert_eq!(child.width, 272); assert_eq!(child.width, 768);
assert_eq!(child.height, 55); assert_eq!(child.height, 154);
} }
} }