Skip to content

Commit d7e359d

Browse files
committed
---
yaml --- r: 81607 b: refs/heads/snap-stage3 c: 33adf6d h: refs/heads/master i: 81605: c64a884 81603: fd70f6e 81599: c5d02f1 v: v3
1 parent 391fe3f commit d7e359d

File tree

4 files changed

+95
-2
lines changed

4 files changed

+95
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 4c6bf4872012c010f84dc7fa2cdfe87522533f89
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 1dfe5088d85df13a172810d0df92c25dbcc37e98
4+
refs/heads/snap-stage3: 33adf6dd6e0dd69af29ee11a1a7a2e11c998938c
55
refs/heads/try: 70152ff55722878cde684ee6462c14c65f2c4729
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libstd/path2/mod.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use clone::Clone;
1616
use iter::Iterator;
1717
use option::{Option, None, Some};
1818
use str;
19-
use str::StrSlice;
19+
use str::{OwnedStr, Str, StrSlice};
2020
use vec;
2121
use vec::{CopyableVector, OwnedCopyableVector, OwnedVector};
2222
use vec::{ImmutableEqVector, ImmutableVector};
@@ -140,6 +140,51 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
140140
/// Returns the path as a byte vector
141141
fn as_vec<'a>(&'a self) -> &'a [u8];
142142

143+
/// Provides the path as a string
144+
///
145+
/// If the path is not UTF-8, invalid sequences will be replaced with the unicode
146+
/// replacement char. This involves allocation.
147+
#[inline]
148+
fn as_display_str<T>(&self, f: &fn(&str) -> T) -> T {
149+
match self.as_str() {
150+
Some(s) => f(s),
151+
None => {
152+
let s = self.to_display_str();
153+
f(s.as_slice())
154+
}
155+
}
156+
}
157+
158+
/// Returns the path as a string
159+
///
160+
/// If the path is not UTF-8, invalid sequences will be replaced with the unicode
161+
/// replacement char. This involves allocation.
162+
///
163+
/// This is similar to `as_display_str()` except it will always allocate a new ~str.
164+
fn to_display_str(&self) -> ~str {
165+
// FIXME (#9516): Don't decode utf-8 manually here once we have a good way to do it in str
166+
// This is a truly horrifically bad implementation, done as a functionality stopgap until
167+
// we have a proper utf-8 decoder. I don't really want to write one here.
168+
static REPLACEMENT_CHAR: char = '\uFFFD';
169+
170+
let mut v = self.as_vec();
171+
let mut s = str::with_capacity(v.len());
172+
while !v.is_empty() {
173+
let w = str::utf8_char_width(v[0]);
174+
if w == 0u {
175+
s.push_char(REPLACEMENT_CHAR);
176+
v = v.slice_from(1);
177+
} else if v.len() < w || !str::is_utf8(v.slice_to(w)) {
178+
s.push_char(REPLACEMENT_CHAR);
179+
v = v.slice_from(1);
180+
} else {
181+
s.push_str(unsafe { ::cast::transmute(v.slice_to(w)) });
182+
v = v.slice_from(w);
183+
}
184+
}
185+
s
186+
}
187+
143188
/// Returns the directory component of `self`, as a byte vector (with no trailing separator).
144189
/// If `self` has no directory component, returns ['.'].
145190
fn dirname<'a>(&'a self) -> &'a [u8];

branches/snap-stage3/src/libstd/path2/posix.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,32 @@ mod tests {
597597
})
598598
}
599599
600+
#[test]
601+
fn test_display_str() {
602+
assert_eq!(Path::from_str("foo").to_display_str(), ~"foo");
603+
assert_eq!(Path::from_vec(b!("foo", 0x80)).to_display_str(), ~"foo\uFFFD");
604+
assert_eq!(Path::from_vec(b!("foo", 0xff, "bar")).to_display_str(), ~"foo\uFFFDbar");
605+
606+
let mut called = false;
607+
do Path::from_str("foo").as_display_str |s| {
608+
assert_eq!(s, "foo");
609+
called = true;
610+
};
611+
assert!(called);
612+
called = false;
613+
do Path::from_vec(b!("foo", 0x80)).as_display_str |s| {
614+
assert_eq!(s, "foo\uFFFD");
615+
called = true;
616+
};
617+
assert!(called);
618+
called = false;
619+
do Path::from_vec(b!("foo", 0xff, "bar")).as_display_str |s| {
620+
assert_eq!(s, "foo\uFFFDbar");
621+
called = true;
622+
};
623+
assert!(called);
624+
}
625+
600626
#[test]
601627
fn test_components() {
602628
macro_rules! t(

branches/snap-stage3/src/libstd/path2/windows.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,16 @@ impl GenericPath for Path {
349349
self.repr.as_bytes()
350350
}
351351

352+
#[inline]
353+
fn as_display_str<T>(&self, f: &fn(&str) -> T) -> T {
354+
f(self.repr.as_slice())
355+
}
356+
357+
#[inline]
358+
fn to_display_str(&self) -> ~str {
359+
self.repr.clone()
360+
}
361+
352362
#[inline]
353363
fn dirname<'a>(&'a self) -> &'a [u8] {
354364
self.dirname_str().unwrap().as_bytes()
@@ -1339,6 +1349,18 @@ mod tests {
13391349
Path::from_vec(b!("hello", 0x80, ".txt"));
13401350
}
13411351
1352+
#[test]
1353+
fn test_display_str() {
1354+
assert_eq!(Path::from_str("foo").to_display_str(), ~"foo");
1355+
1356+
let mut called = false;
1357+
do Path::from_str("foo").as_display_str |s| {
1358+
assert_eq!(s, "foo");
1359+
called = true;
1360+
};
1361+
assert!(called);
1362+
}
1363+
13421364
#[test]
13431365
fn test_components() {
13441366
macro_rules! t(

0 commit comments

Comments
 (0)