1 use std::fmt::Display; 2 use std::fmt::Error; 3 use std::fmt::Formatter; 4 use std::str::FromStr; 5 6 use serde::ser::{Serialize, Serializer}; 7 8 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Hash)] 9 pub enum Field { 10 Name, 11 Path, 12 AbsPath, 13 Extension, 14 Directory, 15 AbsDir, 16 Size, 17 FormattedSize, 18 Uid, 19 Gid, 20 User, 21 Group, 22 Created, 23 Accessed, 24 Modified, 25 IsDir, 26 IsFile, 27 IsSymlink, 28 IsPipe, 29 IsCharacterDevice, 30 IsBlockDevice, 31 IsSocket, 32 Device, 33 Inode, 34 Blocks, 35 Hardlinks, 36 Mode, 37 UserRead, 38 UserWrite, 39 UserExec, 40 UserAll, 41 GroupRead, 42 GroupWrite, 43 GroupExec, 44 GroupAll, 45 OtherRead, 46 OtherWrite, 47 OtherExec, 48 OtherAll, 49 Suid, 50 Sgid, 51 IsHidden, 52 HasXattrs, 53 IsShebang, 54 IsEmpty, 55 Width, 56 Height, 57 Duration, 58 Bitrate, 59 Freq, 60 Title, 61 Artist, 62 Album, 63 Year, 64 Genre, 65 ExifDateTime, 66 ExifGpsAltitude, 67 ExifGpsLatitude, 68 ExifGpsLongitude, 69 ExifMake, 70 ExifModel, 71 ExifSoftware, 72 ExifVersion, 73 Mime, 74 LineCount, 75 IsBinary, 76 IsText, 77 IsArchive, 78 IsAudio, 79 IsBook, 80 IsDoc, 81 IsImage, 82 IsSource, 83 IsVideo, 84 Sha1, 85 Sha256, 86 Sha512, 87 Sha3, 88 } 89 90 impl FromStr for Field { 91 type Err = String; 92 93 fn from_str(s: &str) -> Result<Self, Self::Err> { 94 let field = s.to_ascii_lowercase(); 95 96 match field.as_str() { 97 "name" => Ok(Field::Name), 98 "ext" | "extension" => Ok(Field::Extension), 99 "path" => Ok(Field::Path), 100 "abspath" => Ok(Field::AbsPath), 101 "dir" | "directory" | "dirname" => Ok(Field::Directory), 102 "absdir" => Ok(Field::AbsDir), 103 "size" => Ok(Field::Size), 104 "fsize" | "hsize" => Ok(Field::FormattedSize), 105 "uid" => Ok(Field::Uid), 106 "gid" => Ok(Field::Gid), 107 "user" => Ok(Field::User), 108 "group" => Ok(Field::Group), 109 "created" => Ok(Field::Created), 110 "accessed" => Ok(Field::Accessed), 111 "modified" => Ok(Field::Modified), 112 "is_dir" => Ok(Field::IsDir), 113 "is_file" => Ok(Field::IsFile), 114 "is_symlink" => Ok(Field::IsSymlink), 115 "is_pipe" | "is_fifo" => Ok(Field::IsPipe), 116 "is_char" | "is_character" => Ok(Field::IsCharacterDevice), 117 "is_block" => Ok(Field::IsBlockDevice), 118 "is_socket" => Ok(Field::IsSocket), 119 "device" => Ok(Field::Device), 120 "inode" => Ok(Field::Inode), 121 "blocks" => Ok(Field::Blocks), 122 "hardlinks" => Ok(Field::Hardlinks), 123 "mode" => Ok(Field::Mode), 124 "user_read" => Ok(Field::UserRead), 125 "user_write" => Ok(Field::UserWrite), 126 "user_exec" => Ok(Field::UserExec), 127 "user_all" | "user_rwx" => Ok(Field::UserAll), 128 "group_read" => Ok(Field::GroupRead), 129 "group_write" => Ok(Field::GroupWrite), 130 "group_exec" => Ok(Field::GroupExec), 131 "group_all" | "group_rwx" => Ok(Field::GroupAll), 132 "other_read" => Ok(Field::OtherRead), 133 "other_write" => Ok(Field::OtherWrite), 134 "other_exec" => Ok(Field::OtherExec), 135 "other_all" | "other_rwx" => Ok(Field::OtherAll), 136 "suid" => Ok(Field::Suid), 137 "sgid" => Ok(Field::Sgid), 138 "is_hidden" => Ok(Field::IsHidden), 139 "has_xattrs" => Ok(Field::HasXattrs), 140 "is_shebang" => Ok(Field::IsShebang), 141 "is_empty" => Ok(Field::IsEmpty), 142 "width" => Ok(Field::Width), 143 "height" => Ok(Field::Height), 144 "mime" => Ok(Field::Mime), 145 "line_count" => Ok(Field::LineCount), 146 "duration" => Ok(Field::Duration), 147 "mp3_bitrate" | "bitrate" => Ok(Field::Bitrate), 148 "mp3_freq" | "freq" => Ok(Field::Freq), 149 "mp3_title" | "title" => Ok(Field::Title), 150 "mp3_artist" | "artist" => Ok(Field::Artist), 151 "mp3_album" | "album" => Ok(Field::Album), 152 "mp3_year" => Ok(Field::Year), 153 "mp3_genre" | "genre" => Ok(Field::Genre), 154 "exif_altitude" | "exif_alt" => Ok(Field::ExifGpsAltitude), 155 "exif_datetime" => Ok(Field::ExifDateTime), 156 "exif_latitude" | "exif_lat" => Ok(Field::ExifGpsLatitude), 157 "exif_longitude" | "exif_lon" | "exif_lng" => Ok(Field::ExifGpsLongitude), 158 "exif_make" => Ok(Field::ExifMake), 159 "exif_model" => Ok(Field::ExifModel), 160 "exif_software" => Ok(Field::ExifSoftware), 161 "exif_version" => Ok(Field::ExifVersion), 162 "is_binary" => Ok(Field::IsBinary), 163 "is_text" => Ok(Field::IsText), 164 "is_archive" => Ok(Field::IsArchive), 165 "is_audio" => Ok(Field::IsAudio), 166 "is_book" => Ok(Field::IsBook), 167 "is_doc" => Ok(Field::IsDoc), 168 "is_image" => Ok(Field::IsImage), 169 "is_source" => Ok(Field::IsSource), 170 "is_video" => Ok(Field::IsVideo), 171 "sha1" => Ok(Field::Sha1), 172 "sha2_256" | "sha256" => Ok(Field::Sha256), 173 "sha2_512" | "sha512" => Ok(Field::Sha512), 174 "sha3_512" | "sha3" => Ok(Field::Sha3), 175 _ => { 176 let err = String::from("Unknown field ") + &field; 177 Err(err) 178 } 179 } 180 } 181 } 182 183 impl Display for Field { 184 fn fmt(&self, f: &mut Formatter) -> Result<(), Error>{ 185 write!(f, "{:?}", self) 186 } 187 } 188 189 impl Serialize for Field { 190 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 191 where S: Serializer 192 { 193 serializer.serialize_str(&self.to_string()) 194 } 195 } 196 197 impl Field { 198 pub fn is_numeric_field(&self) -> bool { 199 match self { 200 Field::Size | Field::FormattedSize 201 | Field::Uid | Field::Gid 202 | Field::Width | Field::Height 203 | Field::LineCount 204 | Field::Duration 205 | Field::Bitrate | Field::Freq | Field::Year => true, 206 _ => false 207 } 208 } 209 210 pub fn is_datetime_field(&self) -> bool { 211 match self { 212 Field::Created | Field::Accessed | Field::Modified 213 | Field::ExifDateTime => true, 214 _ => false 215 } 216 } 217 218 pub fn is_available_for_archived_files(&self) -> bool { 219 match self { 220 Field::Name 221 | Field::Extension 222 | Field::Path 223 | Field::AbsPath 224 | Field::Directory 225 | Field::AbsDir 226 | Field::Size 227 | Field::FormattedSize 228 | Field::IsDir 229 | Field::IsFile 230 | Field::IsSymlink 231 | Field::IsPipe 232 | Field::IsCharacterDevice 233 | Field::IsBlockDevice 234 | Field::IsSocket 235 | Field::Mode 236 | Field::UserRead 237 | Field::UserWrite 238 | Field::UserExec 239 | Field::UserAll 240 | Field::GroupRead 241 | Field::GroupWrite 242 | Field::GroupExec 243 | Field::GroupAll 244 | Field::OtherRead 245 | Field::OtherWrite 246 | Field::OtherExec 247 | Field::OtherAll 248 | Field::Suid 249 | Field::Sgid 250 | Field::IsHidden 251 | Field::IsEmpty 252 | Field::Modified 253 | Field::IsArchive 254 | Field::IsAudio 255 | Field::IsBook 256 | Field::IsDoc 257 | Field::IsImage 258 | Field::IsSource 259 | Field::IsVideo 260 => true, 261 _ => false 262 } 263 } 264 265 pub fn is_colorized_field(&self) -> bool { 266 match self { 267 Field::Name => true, 268 _ => false 269 } 270 } 271 }