rsmount/mount/
mount_source_enum.rs1use std::fmt;
8use std::str::FromStr;
9
10use crate::core::device::BlockDevice;
12use crate::core::device::MountPoint;
13use crate::core::device::Pseudo;
14use crate::core::device::SmbFs;
15use crate::core::device::SshFs;
16use crate::core::device::Tag;
17use crate::core::device::NFS;
18use crate::core::errors::ParserError;
19
20#[derive(Debug, Eq, PartialEq)]
84#[non_exhaustive]
85pub enum MountSource {
86 BlockDevice(BlockDevice),
87 MountPoint(MountPoint),
88 NFS(NFS),
89 SmbFs(SmbFs),
90 SshFs(SshFs),
91 Tag(Tag),
92 PseudoFs(Pseudo),
93}
94
95impl MountSource {
96 pub fn is_block_device(&self) -> bool {
98 matches!(self, Self::BlockDevice(_))
99 }
100
101 pub fn is_mount_point(&self) -> bool {
103 matches!(self, Self::MountPoint(_))
104 }
105
106 pub fn is_nfs_share(&self) -> bool {
108 matches!(self, Self::NFS(_))
109 }
110
111 pub fn is_samba_share(&self) -> bool {
113 matches!(self, Self::SmbFs(_))
114 }
115
116 pub fn is_sshfs_share(&self) -> bool {
118 matches!(self, Self::SshFs(_))
119 }
120
121 pub fn is_tag(&self) -> bool {
124 matches!(self, Self::Tag(_))
125 }
126
127 pub fn is_pseudo_fs(&self) -> bool {
129 matches!(self, Self::PseudoFs(_))
130 }
131
132 pub fn is_tag_label(&self) -> bool {
134 matches!(self, Self::Tag(t) if t.is_label())
135 }
136
137 pub fn is_tag_partition_label(&self) -> bool {
139 matches!(self, Self::Tag(t) if t.is_partition_label())
140 }
141
142 pub fn is_tag_uuid(&self) -> bool {
144 matches!(self, Self::Tag(t) if t.is_uuid())
145 }
146
147 pub fn is_tag_partition_uuid(&self) -> bool {
149 matches!(self, Self::Tag(t) if t.is_partition_uuid())
150 }
151
152 pub fn is_tag_id(&self) -> bool {
154 matches!(self, Self::Tag(t) if t.is_id())
155 }
156}
157
158impl AsRef<MountSource> for MountSource {
159 #[inline]
160 fn as_ref(&self) -> &MountSource {
161 self
162 }
163}
164
165impl TryFrom<&str> for MountSource {
166 type Error = ParserError;
167
168 fn try_from(s: &str) -> Result<Self, Self::Error> {
169 Tag::from_str(s)
171 .map(Self::from)
172 .or_else(|_| Pseudo::from_str(s).map(Self::from))
173 .or_else(|_| SmbFs::from_str(s).map(Self::from))
174 .or_else(|_| SshFs::from_str(s).map(Self::from))
175 .or_else(|_| NFS::from_str(s).map(Self::from))
176 .or_else(|_| MountPoint::from_str(s).map(Self::from))
177 .or_else(|_| BlockDevice::from_str(s).map(Self::from))
179 }
180}
181
182impl TryFrom<String> for MountSource {
183 type Error = ParserError;
184
185 #[inline]
186 fn try_from(s: String) -> Result<Self, Self::Error> {
187 Self::try_from(s.as_str())
188 }
189}
190
191impl TryFrom<&String> for MountSource {
192 type Error = ParserError;
193
194 #[inline]
195 fn try_from(s: &String) -> Result<Self, Self::Error> {
196 Self::try_from(s.as_str())
197 }
198}
199
200impl FromStr for MountSource {
201 type Err = ParserError;
202
203 fn from_str(s: &str) -> Result<Self, Self::Err> {
204 Self::try_from(s)
205 }
206}
207
208impl fmt::Display for MountSource {
209 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
210 let output = match self {
211 Self::BlockDevice(device) => device.to_string(),
212 Self::MountPoint(mount_point) => mount_point.to_string(),
213 Self::NFS(share) => share.to_string(),
214 Self::SmbFs(share) => share.to_string(),
215 Self::SshFs(share) => share.to_string(),
216 Self::Tag(tag) => tag.to_string(),
217 Self::PseudoFs(fs) => fs.to_string(),
218 };
219
220 write!(f, "{}", output)
221 }
222}
223
224impl From<BlockDevice> for MountSource {
225 #[inline]
226 fn from(device: BlockDevice) -> MountSource {
227 MountSource::BlockDevice(device)
228 }
229}
230
231impl From<MountPoint> for MountSource {
232 #[inline]
233 fn from(mount_point: MountPoint) -> MountSource {
234 MountSource::MountPoint(mount_point)
235 }
236}
237
238impl From<NFS> for MountSource {
239 #[inline]
240 fn from(share: NFS) -> MountSource {
241 MountSource::NFS(share)
242 }
243}
244
245impl From<SmbFs> for MountSource {
246 #[inline]
247 fn from(share: SmbFs) -> MountSource {
248 MountSource::SmbFs(share)
249 }
250}
251
252impl From<SshFs> for MountSource {
253 #[inline]
254 fn from(share: SshFs) -> MountSource {
255 MountSource::SshFs(share)
256 }
257}
258
259impl From<Tag> for MountSource {
260 #[inline]
261 fn from(share: Tag) -> MountSource {
262 MountSource::Tag(share)
263 }
264}
265
266impl From<Pseudo> for MountSource {
267 #[inline]
268 fn from(fs: Pseudo) -> MountSource {
269 MountSource::PseudoFs(fs)
270 }
271}
272
273#[cfg(test)]
274#[allow(unused_imports)]
275mod tests {
276 use super::*;
277 use pretty_assertions::{assert_eq, assert_ne};
278
279 #[test]
280 #[should_panic(expected = "expected a device path instead of")]
281 fn mount_source_does_not_parse_an_empty_string_as_a_block_device() {
282 let source = "";
283 let _ = MountSource::try_from(source).unwrap();
284 }
285
286 #[test]
287 fn mount_source_parses_a_block_device() -> crate::Result<()> {
288 let source = "/dev/vda";
289 let actual: MountSource = source.parse()?;
290
291 assert!(actual.is_block_device());
292
293 Ok(())
294 }
295
296 #[test]
297 fn mount_source_parses_a_mount_point() -> crate::Result<()> {
298 let source = "/boot";
299 let actual: MountSource = source.parse()?;
300
301 assert!(actual.is_mount_point());
302
303 Ok(())
304 }
305
306 #[test]
307 fn mount_source_parses_a_nfs_share_address_as_an_sshfs_share() -> crate::Result<()> {
308 let source = "localhost:/share";
309 let actual: MountSource = source.parse()?;
310
311 assert!(actual.is_sshfs_share());
312
313 Ok(())
314 }
315
316 #[test]
317 fn mount_source_parses_a_samba_share_address() -> crate::Result<()> {
318 let source = "smb://localhost/share";
319 let actual: MountSource = source.parse()?;
320
321 assert!(actual.is_samba_share());
322
323 Ok(())
324 }
325
326 #[test]
327 fn mount_source_parses_a_sshfs_share_address() -> crate::Result<()> {
328 let source = "user@localhost:/share";
329 let actual: MountSource = source.parse()?;
330
331 assert!(actual.is_sshfs_share());
332
333 Ok(())
334 }
335
336 #[test]
337 fn mount_source_parses_a_uuid_tag() -> crate::Result<()> {
338 let source = "UUID=dd476616-1ce4-415e-9dbd-8c2fa8f42f0f";
339 let actual: MountSource = source.parse()?;
340
341 assert!(actual.is_tag_uuid());
342
343 Ok(())
344 }
345
346 #[test]
347 fn mount_source_parses_a_pseudo_fs() -> crate::Result<()> {
348 let source = "none";
349 let actual: MountSource = source.parse()?;
350
351 assert!(actual.is_pseudo_fs());
352
353 Ok(())
354 }
355}