Skip to content

Commit 1fb0ce1

Browse files
Merge pull request #6 from andrewdavidmackenzie/simpath-5
simpath-5 Fixes #5
2 parents b7d8c90 + da347ea commit 1fb0ce1

File tree

2 files changed

+96
-13
lines changed

2 files changed

+96
-13
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "simpath"
3-
version = "1.3.1"
3+
version = "1.4.1"
44
authors = ["Andrew Mackenzie <andrew@mackenzie-serres.net>"]
55
description = "Search for files on a path defined in an environment variable"
66
license = "MIT"

src/lib.rs

Lines changed: 95 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,44 @@
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+
//!
18
use std::path::PathBuf;
29
use std::fmt;
310
use std::env;
411
use std::fs;
512
use 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`
817
pub 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
1425
pub 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+
2042
impl 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

193255
impl 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

Comments
 (0)