ssh_transfer/sftp/
list.rs

1use 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}