1+ #![ deny( missing_docs) ]
2+ //! Simpath - or Simple Path is a small library for creating, manipulating and using Unix style
3+ //! `Path`s.
4+ //!
5+ //! A `Path` is an environment variable (a String) with one or more colon-separated directories
6+ //! specified. They are usually used to find a file that resides in one of the directories.
7+ //!
18use std:: path:: PathBuf ;
29use std:: fmt;
310use std:: env;
411use std:: fs;
512use std:: io:: { Error , ErrorKind } ;
613
714#[ derive( Clone , Debug ) ]
15+ /// `Simpath` is the struct returned when you create a new on using a named environment variable
16+ /// which you then use to interact with the `Path`
817pub struct Simpath {
918 name : String ,
10- dirs : Vec < PathBuf >
19+ entries : Vec < PathBuf >
1120}
1221
1322#[ derive( Debug ) ]
23+ /// `FileType` can be used to find an entry in a path of a specific type (`Directory`, `File`) or
24+ /// of `Any` type
1425pub enum FileType {
26+ /// An entry in the `Path` of type `File`
1527 File ,
28+ /// An entry in the `Path` of type `Directory`
1629 Directory ,
30+ /// An entry in the `Path` of `Any` types
1731 Any
1832}
1933
34+ /// When validating a `Path` there can be the following types of `PathError`s returned
35+ pub enum PathError {
36+ /// The `Path` entry does not exist on the file system
37+ DoesNotExist ( String ) ,
38+ /// The `Path` entry cannot be reads
39+ CannotRead ( String )
40+ }
41+
2042impl Simpath {
2143 /// Create a new simpath, providing the name of the environment variable to initialize the
2244 /// search path with. If an environment variable of that name exists and it will be parsed
@@ -44,7 +66,7 @@ impl Simpath {
4466 pub fn new ( var_name : & str ) -> Self {
4567 let mut search_path = Simpath {
4668 name : var_name. to_string ( ) ,
47- dirs : vec ! ( )
69+ entries : vec ! ( )
4870 } ;
4971
5072 search_path. add_from_env_var ( var_name) ;
@@ -53,6 +75,15 @@ impl Simpath {
5375 }
5476
5577 /// Get the name associated with the simpath. Note that this could be an empty String
78+ /// ```
79+ /// extern crate simpath;
80+ /// use simpath::Simpath;
81+ ///
82+ /// fn main() {
83+ /// let search_path = Simpath::new("PATH");
84+ /// println!("Directories in Search Path: {:?}", search_path.name());
85+ /// }
86+ /// ```
5687 pub fn name ( & self ) -> & str {
5788 & self . name
5889 }
@@ -70,7 +101,7 @@ impl Simpath {
70101 /// ```
71102 ///
72103 pub fn directories ( & self ) -> & Vec < PathBuf > {
73- & self . dirs
104+ & self . entries
74105 }
75106
76107 /// Try to find a file by filename (not full path) on a search path.
@@ -95,8 +126,23 @@ impl Simpath {
95126 self . find_type ( file_name, FileType :: Any )
96127 }
97128
129+ /// find an entry of a specific `FileType` in a `Path`
130+ ///
131+ /// ```
132+ /// extern crate simpath;
133+ /// use simpath::Simpath;
134+ ///
135+ /// fn main() {
136+ /// use simpath::FileType;
137+ /// let search_path = Simpath::new("PATH");
138+ /// match search_path.find_type("my-file", FileType::Directory) {
139+ /// Ok(_found_dir) => println!("Didn't expect that!!"),
140+ /// Err(e) => println!("{}", e.to_string())
141+ /// }
142+ /// }
143+ /// ```
98144 pub fn find_type ( & self , file_name : & str , file_type : FileType ) -> Result < PathBuf , Error > {
99- for search_dir in & self . dirs {
145+ for search_dir in & self . entries {
100146 for entry in fs:: read_dir ( search_dir) ? {
101147 let file = entry?;
102148 if let Some ( filename) = file. file_name ( ) . to_str ( ) {
@@ -136,13 +182,11 @@ impl Simpath {
136182 pub fn add_directory ( & mut self , dir : & str ) {
137183 let path = PathBuf :: from ( dir) ;
138184 if path. exists ( ) && path. is_dir ( ) && path. read_dir ( ) . is_ok ( ) {
139- self . dirs . push ( path) ;
185+ self . entries . push ( path) ;
140186 }
141187 }
142188
143- /// Check if a search path contains a directory
144- ///
145- ///
189+ /// Check if a search path contains an entry
146190 /// ```
147191 /// extern crate simpath;
148192 /// use simpath::Simpath;
@@ -154,9 +198,9 @@ impl Simpath {
154198 /// }
155199 /// }
156200 /// ```
157- pub fn contains ( & self , dir : & str ) -> bool {
158- for search_dir in & self . dirs {
159- if search_dir. to_str ( ) . unwrap ( ) == dir {
201+ pub fn contains ( & self , entry : & str ) -> bool {
202+ for search_dir in & self . entries {
203+ if search_dir. to_str ( ) . unwrap ( ) == entry {
160204 return true ;
161205 }
162206 }
@@ -188,12 +232,30 @@ impl Simpath {
188232 }
189233 }
190234 }
235+
236+ /// `validate` checks that all the entries in the `Path` are of a valid syntax, exist on
237+ /// the file system and can be read
238+ pub fn validate ( & self ) -> Vec < PathError > {
239+ let mut errors = vec ! ( ) ;
240+
241+ for entry in & self . entries {
242+ if !entry. exists ( ) {
243+ errors. push ( PathError :: DoesNotExist ( entry. to_str ( ) . unwrap ( ) . into ( ) ) ) ;
244+ }
245+
246+ if fs:: metadata ( entry) . is_err ( ) {
247+ errors. push ( PathError :: CannotRead ( entry. to_str ( ) . unwrap ( ) . into ( ) ) ) ;
248+ }
249+ }
250+
251+ errors
252+ }
191253}
192254
193255impl fmt:: Display for Simpath {
194256 fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
195257 write ! ( f, "Search Path: '{}', Directories: {{" , self . name) . unwrap ( ) ;
196- for dir in & self . dirs {
258+ for dir in & self . entries {
197259 write ! ( f, "'{}', " , dir. display( ) ) . unwrap ( ) ;
198260
199261 }
@@ -354,4 +416,25 @@ mod test {
354416
355417 println ! ( "Simpath can be printed: {}" , path) ;
356418 }
419+
420+ #[ test]
421+ fn entry_does_not_exist ( ) {
422+ let var_name = "MyPathEnv" ;
423+ env:: set_var ( var_name, "/foo" ) ;
424+ let mut path = Simpath :: new ( "MyName" ) ;
425+ path. add_from_env_var ( var_name) ;
426+
427+ assert_eq ! ( path. directories( ) . len( ) , 0 ) ;
428+ }
429+
430+ #[ test]
431+ fn one_entry_does_not_exist ( ) {
432+ let var_name = "MyPathEnv" ;
433+ env:: set_var ( var_name, ".:/foo" ) ;
434+ let mut path = Simpath :: new ( "MyName" ) ;
435+ path. add_from_env_var ( var_name) ;
436+
437+ assert_eq ! ( path. directories( ) . len( ) , 1 ) ;
438+ assert_eq ! ( path. validate( ) . len( ) , 0 ) ;
439+ }
357440}
0 commit comments