path_filetype/
unix.rs

1//use std::fs;
2use std::io::{self, ErrorKind};
3use std::path::{Path, PathBuf};
4use std::os::unix::fs::FileTypeExt;
5
6#[derive(Clone, Debug, Hash, PartialEq)]
7pub enum FileType {
8    Regular,
9    Directory,
10    Symlink,
11    CharDevice,
12    BlockDevice,
13    Fifo,
14    Socket,
15}
16
17// TODO
18#[derive(Clone, Debug, Hash, PartialEq)]
19pub enum Regular {
20    ASCII,
21    OTHER,
22}
23
24pub trait PathFileType {
25    /// 返回一个枚举类型结果 FileType
26    fn filetype(&self) -> io::Result<FileType>;
27
28    /// 判断路径是否为一个链接
29    fn is_symlink(&self) -> bool;
30
31    /// 判断路径是否为字符设备文件
32    fn is_char_device(&self) -> bool;
33
34    /// 判断路径是否为块设备文件
35    fn is_block_device(&self) -> bool;
36
37    /// 判断路径是否为管道文件
38    fn is_fifo(&self) -> bool;
39
40    /// 判断路径是否为套接字文件
41    fn is_socket(&self) -> bool;
42}
43
44impl PathFileType for Path {
45    fn filetype(&self) -> io::Result<FileType> {
46        // 确认文件存在
47        if ! self.exists() {
48            return Err(io::Error::from(ErrorKind::NotFound))
49        }
50
51        if self.is_block_device() {
52            Ok(FileType::BlockDevice) 
53        } else if self.is_char_device() {
54            Ok(FileType::CharDevice)
55        } else if self.is_fifo() {
56            Ok(FileType::Fifo)
57        } else if self.is_socket() {
58            Ok(FileType::Socket)
59        } else if self.is_symlink() {
60            Ok(FileType::Symlink)
61        } else if self.is_dir() {
62            Ok(FileType::Directory)
63        } else {
64            Ok(FileType::Regular)
65        }
66    }
67
68    fn is_symlink(&self) -> bool {
69        self.symlink_metadata().unwrap().file_type().is_symlink()
70    }
71
72    fn is_char_device(&self) -> bool {
73        self.metadata().unwrap().file_type().is_char_device()
74    }
75
76    fn is_block_device(&self) -> bool {
77        self.metadata().unwrap().file_type().is_block_device()
78    }
79
80    fn is_fifo(&self) -> bool {
81        self.metadata().unwrap().file_type().is_fifo()
82    }
83
84    fn is_socket(&self) -> bool {
85        self.metadata().unwrap().file_type().is_socket()
86    }
87}
88
89impl PathFileType for PathBuf {
90    fn filetype(&self) -> io::Result<FileType> {
91        self.as_path().filetype()
92    }
93
94    fn is_symlink(&self) -> bool {
95        self.as_path().is_symlink()
96    }
97
98    fn is_char_device(&self) -> bool {
99        self.as_path().is_char_device()
100    }
101
102    fn is_block_device(&self) -> bool {
103        self.as_path().is_block_device()
104    }
105
106    fn is_fifo(&self) -> bool {
107        self.as_path().is_fifo()
108    }
109
110    fn is_socket(&self) -> bool {
111        self.as_path().is_socket()
112    }
113}