about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorKevin Ballard <kevin@sb.org>2013-10-01 14:03:41 -0700
committerKevin Ballard <kevin@sb.org>2013-10-15 20:10:11 -0700
commit6741241f4046aea4014b1a23618593fb481c8606 (patch)
tree0e7c17333e81edc80df9e56ea32984ad7d79ee22 /src/libstd
parent3a2735cb11efc997aa02646c13c008a883de6792 (diff)
downloadrust-6741241f4046aea4014b1a23618593fb481c8606.tar.gz
rust-6741241f4046aea4014b1a23618593fb481c8606.zip
path2: Add format helpers .display() and .filename_display()
These methods return an object that can be formatted using {} to print
display strings.

Path itself does not implement fmt::Default to avoid accidental usage of
display strings in incorrect places (e.g. process arguments).
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/path2/mod.rs41
-rw-r--r--src/libstd/path2/posix.rs23
-rw-r--r--src/libstd/path2/windows.rs19
3 files changed, 83 insertions, 0 deletions
diff --git a/src/libstd/path2/mod.rs b/src/libstd/path2/mod.rs
index e385cea51f9..38a48866e22 100644
--- a/src/libstd/path2/mod.rs
+++ b/src/libstd/path2/mod.rs
@@ -13,6 +13,7 @@
 use container::Container;
 use c_str::CString;
 use clone::Clone;
+use fmt;
 use iter::Iterator;
 use option::{Option, None, Some};
 use str;
@@ -185,6 +186,21 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
         s
     }
 
+    /// Returns an object that implements `fmt::Default` for printing paths
+    ///
+    /// This will print the equivalent of `to_display_str()` when used with a {} format parameter.
+    fn display<'a>(&'a self) -> Display<'a, Self> {
+        Display{ path: self }
+    }
+
+    /// Returns an object that implements `fmt::Default` for printing filenames
+    ///
+    /// This will print the equivalent of `to_filename_display_str()` when used with a {}
+    /// format parameter. If there is no filename, nothing will be printed.
+    fn filename_display<'a>(&'a self) -> FilenameDisplay<'a, Self> {
+        FilenameDisplay{ path: self }
+    }
+
     /// Returns the directory component of `self`, as a byte vector (with no trailing separator).
     /// If `self` has no directory component, returns ['.'].
     fn dirname<'a>(&'a self) -> &'a [u8];
@@ -661,6 +677,31 @@ pub trait GenericPathUnsafe {
     }
 }
 
+/// Helper struct for printing paths with format!()
+pub struct Display<'self, P> {
+    priv path: &'self P
+}
+/// Helper struct for printing filenames with format!()
+pub struct FilenameDisplay<'self, P> {
+    priv path: &'self P
+}
+
+impl<'self, P: GenericPath> fmt::Default for Display<'self, P> {
+    fn fmt(d: &Display<P>, f: &mut fmt::Formatter) {
+        do d.path.with_display_str |s| {
+            f.pad(s)
+        }
+    }
+}
+
+impl<'self, P: GenericPath> fmt::Default for FilenameDisplay<'self, P> {
+    fn fmt(d: &FilenameDisplay<P>, f: &mut fmt::Formatter) {
+        do d.path.with_filename_display_str |s| {
+            f.pad(s.unwrap_or(""))
+        }
+    }
+}
+
 #[inline(always)]
 fn contains_nul(v: &[u8]) -> bool {
     v.iter().any(|&x| x == 0)
diff --git a/src/libstd/path2/posix.rs b/src/libstd/path2/posix.rs
index 233458dfc9b..4aa2eb531e5 100644
--- a/src/libstd/path2/posix.rs
+++ b/src/libstd/path2/posix.rs
@@ -731,6 +731,29 @@ mod tests {
     }
 
     #[test]
+    fn test_display() {
+        macro_rules! t(
+            ($path:expr, $exp:expr, $expf:expr) => (
+                {
+                    let path = Path::from_vec($path);
+                    let f = format!("{}", path.display());
+                    assert_eq!(f.as_slice(), $exp);
+                    let f = format!("{}", path.filename_display());
+                    assert_eq!(f.as_slice(), $expf);
+                }
+            )
+        )
+
+        t!(b!("foo"), "foo", "foo");
+        t!(b!("foo/bar"), "foo/bar", "bar");
+        t!(b!("/"), "/", "");
+        t!(b!("foo", 0xff), "foo\uFFFD", "foo\uFFFD");
+        t!(b!("foo", 0xff, "/bar"), "foo\uFFFD/bar", "bar");
+        t!(b!("foo/", 0xff, "bar"), "foo/\uFFFDbar", "\uFFFDbar");
+        t!(b!(0xff, "foo/bar", 0xff), "\uFFFDfoo/bar\uFFFD", "bar\uFFFD");
+    }
+
+    #[test]
     fn test_components() {
         macro_rules! t(
             (s: $path:expr, $op:ident, $exp:expr) => (
diff --git a/src/libstd/path2/windows.rs b/src/libstd/path2/windows.rs
index c23dc86d7df..7cc7a5610bd 100644
--- a/src/libstd/path2/windows.rs
+++ b/src/libstd/path2/windows.rs
@@ -1458,6 +1458,25 @@ mod tests {
     }
 
     #[test]
+    fn test_display() {
+        macro_rules! t(
+            ($path:expr, $exp:expr, $expf:expr) => (
+                {
+                    let path = Path::from_str($path);
+                    let f = format!("{}", path.display());
+                    assert_eq!(f.as_slice(), $exp);
+                    let f = format!("{}", path.filename_display());
+                    assert_eq!(f.as_slice(), $expf);
+                }
+            )
+        )
+
+        t!("foo", "foo", "foo");
+        t!("foo\\bar", "foo\\bar", "bar");
+        t!("\\", "\\", "");
+    }
+
+    #[test]
     fn test_components() {
         macro_rules! t(
             (s: $path:expr, $op:ident, $exp:expr) => (