rpf/utils/
pathmod.rs

1// Copyright (C) 2015, Alberto Corona <alberto@0x1a.us>
2// All rights reserved. This file is part of rpf, distributed under the
3// BSD 3-Clause license. For full terms please see the LICENSE file.
4
5use std::path::{PathBuf,Path};
6
7/// Adds some useful functions for manipulating and retrieving information from
8/// paths
9pub trait PathMod {
10    /// Returns true if the path's file name starts with a "."
11    ///
12    /// # Example
13    ///
14    /// ```
15    /// use rpf::PathMod;
16    /// use std::path::Path;
17    ///
18    /// let path = Path::new("/test/dot/.dotfile");
19    /// assert_eq!(path.is_dot(), true);
20    fn is_dot(&self) -> bool;
21
22    /// Returns a `PathBuf` of `&self`'s last component
23    ///
24    /// # Example
25    ///
26    /// ```
27    /// use rpf::PathMod;
28    /// use std::path::PathBuf;
29    ///
30    /// let path = PathBuf::from("/tmp/test/mod");
31    /// let last = path.last_component().unwrap();
32    /// assert_eq!(last, PathBuf::from("mod"));
33    /// ```
34    fn last_component(&self) -> Option<PathBuf>;
35
36    /// Returns a `PathBuf` of `&self`'s first component
37    ///
38    /// # Example
39    /// ```
40    /// use rpf::PathMod;
41    /// use std::path::PathBuf;
42    ///
43    /// let path = PathBuf::from("/tmp/test/mod");
44    /// let first = path.first_component().unwrap();
45    /// assert_eq!(first, PathBuf::from("/"));
46    /// ```
47    fn first_component(&self) -> Option<PathBuf>;
48
49    /// Returns a `&str` for a path, returns a blank string if unable to
50    /// get a string for the path
51    ///
52    /// # Example
53    /// ```
54    /// use rpf::PathMod;
55    /// use std::path::PathBuf;
56    ///
57    /// let path = PathBuf::from("/usr/share");
58    /// let path_str = &path.as_str();
59    /// assert_eq!(path_str, &"/usr/share");
60    /// ```
61    fn as_str(&self) -> &str;
62
63    /// Returns a `String` for a path, returns an empty string if unable to get
64    /// a string for a path
65    ///
66    /// # Example
67    /// ```
68    /// use rpf::PathMod;
69    /// use std::path::PathBuf;
70    ///
71    /// let path_string = PathBuf::from("/var/log/test").as_string();
72    /// assert_eq!(path_string, "/var/log/test".to_string());
73    /// ```
74    fn as_string(&self) -> String;
75}
76
77impl PathMod for PathBuf {
78    fn is_dot(&self) -> bool {
79        let file_name = match self.file_name() {
80            Some(s) => {
81                match s.to_str() {
82                    Some(k) => { k },
83                    None => { return false; }
84                }
85            },
86            None => { return false; }
87        };
88        if file_name.starts_with(".") { return true; }
89        else { return false; }
90    }
91
92    fn last_component(&self) -> Option<PathBuf> {
93        match self.components().last() {
94            Some(s) => { Some(PathBuf::from(s.as_os_str())) },
95            None => { None },
96        }
97    }
98
99    fn first_component(&self) -> Option<PathBuf> {
100        match self.components().nth(0) {
101            Some(s) => { Some(PathBuf::from(s.as_os_str())) },
102            None => { None },
103        }
104    }
105
106    fn as_str(&self) -> &str {
107        match self.to_str() {
108            Some(s) => { s },
109            None => { "" },
110        }
111    }
112
113    fn as_string(&self) -> String {
114        self.as_str().to_string()
115    }
116}
117
118impl PathMod for Path {
119    fn is_dot(&self) -> bool {
120        let file_name = match self.file_name() {
121            Some(s) => {
122                match s.to_str() {
123                    Some(k) => { k },
124                    None => { "" }
125                }
126            },
127            None => { "" }
128        };
129        if file_name.starts_with(".") { return true; }
130        else { return false; }
131    }
132
133    fn last_component(&self) -> Option<PathBuf> {
134        match self.components().last() {
135            Some(s) => { Some(PathBuf::from(s.as_os_str())) },
136            None => { None },
137        }
138    }
139
140    fn first_component(&self) -> Option<PathBuf> {
141        match self.components().nth(0) {
142            Some(s) => { Some(PathBuf::from(s.as_os_str())) },
143            None => { None },
144        }
145    }
146
147    fn as_str(&self) -> &str {
148        match self.to_str() {
149            Some(s) => { s },
150            None => { "" },
151        }
152    }
153
154    fn as_string(&self) -> String {
155        self.as_str().to_string()
156    }
157}
158
159#[test]
160fn test_pathmod_first_comp() {
161    let comp = Path::new("/etc/test").first_component().unwrap();
162    assert_eq!(comp, PathBuf::from("/"));
163}
164
165#[test]
166fn test_pathmod_last_comp() {
167    let comp = Path::new("/etc/test").last_component().unwrap();
168    assert_eq!(comp, PathBuf::from("test"));
169}
170
171#[test]
172fn test_pathmod_as_str() {
173    let string = Path::new("/var/log/test").as_str();
174    assert_eq!(string, "/var/log/test");
175}
176
177#[test]
178fn test_pathmod_as_string() {
179    let string = Path::new("/var/log/test").as_string();
180    assert_eq!(string, "/var/log/test".to_string());
181}
182
183#[test]
184fn test_pathmod_is_dot_success() {
185    let path = Path::new("/dir/test/.test");
186    assert_eq!(path.is_dot(), true);
187}
188
189#[test]
190#[should_panic]
191fn test_pathmod_is_dot_fail() {
192    let false_path = Path::new("/");
193    assert_eq!(false_path.is_dot(), true);
194}