@@ -20,6 +20,17 @@ pub fn path_absolute_form(path: &Path) -> io::Result<PathBuf> {
2020 env:: current_dir ( ) . map ( |path_buf| path_buf. join ( path) )
2121}
2222
23+ /// Construct an absolute path from a potentially relative path and a
24+ /// pre-resolved working directory. Unlike `path_absolute_form`, this
25+ /// does not call `env::current_dir()` and cannot fail.
26+ pub fn make_absolute ( path : & Path , cwd : & Path ) -> PathBuf {
27+ if path. is_absolute ( ) {
28+ return path. to_path_buf ( ) ;
29+ }
30+ let path = path. strip_prefix ( "." ) . unwrap_or ( path) ;
31+ cwd. join ( path)
32+ }
33+
2334pub fn absolute_path ( path : & Path ) -> io:: Result < PathBuf > {
2435 let path_buf = path_absolute_form ( path) ?;
2536
@@ -153,4 +164,40 @@ mod tests {
153164 Path :: new( "foo/bar/baz" )
154165 ) ;
155166 }
167+
168+ #[ test]
169+ fn make_absolute_with_relative_path ( ) {
170+ use super :: make_absolute;
171+ use std:: path:: PathBuf ;
172+
173+ let cwd = Path :: new ( "/home/user" ) ;
174+ assert_eq ! (
175+ make_absolute( Path :: new( "foo/bar" ) , cwd) ,
176+ PathBuf :: from( "/home/user/foo/bar" )
177+ ) ;
178+ }
179+
180+ #[ test]
181+ fn make_absolute_strips_dot_prefix ( ) {
182+ use super :: make_absolute;
183+ use std:: path:: PathBuf ;
184+
185+ let cwd = Path :: new ( "/home/user" ) ;
186+ assert_eq ! (
187+ make_absolute( Path :: new( "./foo/bar" ) , cwd) ,
188+ PathBuf :: from( "/home/user/foo/bar" )
189+ ) ;
190+ }
191+
192+ #[ test]
193+ fn make_absolute_with_absolute_path ( ) {
194+ use super :: make_absolute;
195+ use std:: path:: PathBuf ;
196+
197+ let cwd = Path :: new ( "/home/user" ) ;
198+ assert_eq ! (
199+ make_absolute( Path :: new( "/absolute/path" ) , cwd) ,
200+ PathBuf :: from( "/absolute/path" )
201+ ) ;
202+ }
156203}
0 commit comments