ssh_transfer/sftp/
list.rs1use crate::error::Result;
2use ssh2::{FileStat, FileType, Session};
3use std::path::{Path, PathBuf};
4
5pub fn list(session: &Session, path: &str) -> Result<Vec<SftpEntry>> {
6 let files = session
7 .sftp()?
8 .readdir(Path::new(path))?
9 .iter()
10 .map(SftpEntry::from)
11 .collect();
12
13 Ok(files)
14}
15
16pub struct SftpEntry {
17 path: String,
18 size: Option<u64>,
19 user_id: Option<u32>,
20 group_id: Option<u32>,
21 permissions: Option<u32>,
22 last_access_time: Option<u64>,
23 last_modification_time: Option<u64>,
24 kind: SftpEntryKind,
25}
26
27impl SftpEntry {
28 pub fn path(&self) -> &str {
29 &self.path
30 }
31 pub fn size(&self) -> &Option<u64> {
32 &self.size
33 }
34 pub fn user_id(&self) -> &Option<u32> {
35 &self.user_id
36 }
37 pub fn group_id(&self) -> &Option<u32> {
38 &self.group_id
39 }
40 pub fn permissions(&self) -> &Option<u32> {
41 &self.permissions
42 }
43 pub fn last_access_time(&self) -> &Option<u64> {
44 &self.last_access_time
45 }
46 pub fn last_modification_time(&self) -> &Option<u64> {
47 &self.last_modification_time
48 }
49 pub fn kind(&self) -> &SftpEntryKind {
50 &self.kind
51 }
52}
53
54impl From<&(PathBuf, FileStat)> for SftpEntry {
55 fn from((path, file_stat): &(PathBuf, FileStat)) -> Self {
56 Self {
57 path: path.to_str().unwrap_or_default().to_string(),
58 size: file_stat.size,
59 user_id: file_stat.uid,
60 group_id: file_stat.gid,
61 permissions: file_stat.perm,
62 last_access_time: file_stat.atime,
63 last_modification_time: file_stat.mtime,
64 kind: SftpEntryKind::from(file_stat.file_type()),
65 }
66 }
67}
68
69pub enum SftpEntryKind {
70 File,
71 Directory,
72 SymLink,
73 Other,
74}
75
76impl From<FileType> for SftpEntryKind {
77 fn from(file_type: FileType) -> Self {
78 match file_type {
79 FileType::Directory => SftpEntryKind::Directory,
80 FileType::RegularFile => SftpEntryKind::File,
81 FileType::Symlink => SftpEntryKind::SymLink,
82 _ => SftpEntryKind::Other,
83 }
84 }
85}