Skip to main content

remote_fs/
types.rs

1use std::path::PathBuf;
2use std::time::SystemTime;
3
4/// Supported remote protocols.
5///
6/// Variants always exist for stable API; backends are gated by Cargo features.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum Protocol {
9    Smb,
10    Ftp,
11    Sftp,
12}
13
14/// File or directory entry returned by listing.
15#[derive(Debug, Clone)]
16pub struct FileEntry {
17    pub path: PathBuf,
18    pub name: String,
19    pub is_dir: bool,
20    pub is_file: bool,
21    pub is_symlink: bool,
22    pub size: u64,
23    pub modified: Option<SystemTime>,
24}
25
26/// Metadata for a remote path.
27#[derive(Debug, Clone)]
28pub struct FileMeta {
29    pub path: PathBuf,
30    pub is_dir: bool,
31    pub is_file: bool,
32    pub is_symlink: bool,
33    pub size: u64,
34    pub modified: Option<SystemTime>,
35}
36
37/// SMB connection configuration.
38#[cfg(feature = "smb")]
39#[derive(Debug, Clone)]
40pub struct SmbConfig {
41    pub host: String,
42    pub share: String,
43    pub username: String,
44    pub password: String,
45    pub port: Option<u16>,
46    pub workgroup: Option<String>,
47}
48
49#[cfg(feature = "smb")]
50impl SmbConfig {
51    pub fn new(
52        host: impl Into<String>,
53        share: impl Into<String>,
54        username: impl Into<String>,
55        password: impl Into<String>,
56    ) -> Self {
57        Self {
58            host: host.into(),
59            share: share.into(),
60            username: username.into(),
61            password: password.into(),
62            port: None,
63            workgroup: None,
64        }
65    }
66
67    pub fn port(mut self, port: u16) -> Self {
68        self.port = Some(port);
69        self
70    }
71
72    pub fn workgroup(mut self, workgroup: impl Into<String>) -> Self {
73        self.workgroup = Some(workgroup.into());
74        self
75    }
76}
77
78/// FTP connection configuration.
79#[cfg(feature = "ftp")]
80#[derive(Debug, Clone)]
81pub struct FtpConfig {
82    pub host: String,
83    pub port: u16,
84    pub username: String,
85    pub password: String,
86    pub passive: bool,
87}
88
89#[cfg(feature = "ftp")]
90impl FtpConfig {
91    pub fn new(
92        host: impl Into<String>,
93        username: impl Into<String>,
94        password: impl Into<String>,
95    ) -> Self {
96        Self {
97            host: host.into(),
98            port: 21,
99            username: username.into(),
100            password: password.into(),
101            passive: true,
102        }
103    }
104
105    pub fn port(mut self, port: u16) -> Self {
106        self.port = port;
107        self
108    }
109
110    pub fn passive(mut self, passive: bool) -> Self {
111        self.passive = passive;
112        self
113    }
114}
115
116/// SFTP connection configuration.
117#[cfg(feature = "sftp")]
118#[derive(Debug, Clone)]
119pub struct SftpConfig {
120    pub host: String,
121    pub port: u16,
122    pub username: String,
123    pub password: Option<String>,
124    pub private_key_path: Option<PathBuf>,
125}
126
127#[cfg(feature = "sftp")]
128impl SftpConfig {
129    pub fn with_password(
130        host: impl Into<String>,
131        username: impl Into<String>,
132        password: impl Into<String>,
133    ) -> Self {
134        Self {
135            host: host.into(),
136            port: 22,
137            username: username.into(),
138            password: Some(password.into()),
139            private_key_path: None,
140        }
141    }
142
143    pub fn with_key(
144        host: impl Into<String>,
145        username: impl Into<String>,
146        private_key_path: impl Into<PathBuf>,
147    ) -> Self {
148        Self {
149            host: host.into(),
150            port: 22,
151            username: username.into(),
152            password: None,
153            private_key_path: Some(private_key_path.into()),
154        }
155    }
156
157    pub fn port(mut self, port: u16) -> Self {
158        self.port = port;
159        self
160    }
161}
162
163/// Generic connection configuration.
164#[derive(Debug, Clone)]
165pub enum Config {
166    #[cfg(feature = "smb")]
167    Smb(SmbConfig),
168    #[cfg(feature = "ftp")]
169    Ftp(FtpConfig),
170    #[cfg(feature = "sftp")]
171    Sftp(SftpConfig),
172}
173
174impl Config {
175    pub fn protocol(&self) -> Protocol {
176        match self {
177            #[cfg(feature = "smb")]
178            Config::Smb(_) => Protocol::Smb,
179            #[cfg(feature = "ftp")]
180            Config::Ftp(_) => Protocol::Ftp,
181            #[cfg(feature = "sftp")]
182            Config::Sftp(_) => Protocol::Sftp,
183            // When no protocol features are enabled, `Config` has no variants.
184            #[cfg(not(any(feature = "smb", feature = "ftp", feature = "sftp")))]
185            _ => unreachable!("enable at least one of: smb, ftp, sftp"),
186        }
187    }
188}