Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
4b7d4cd0
R
Rust
项目概览
int
/
Rust
大约 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4b7d4cd0
编写于
9月 28, 2012
作者:
G
Graydon Hoare
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
De-export str. Part of #3583.
上级
9e0a43c9
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
124 addition
and
251 deletion
+124
-251
src/libcore/core.rc
src/libcore/core.rc
+0
-1
src/libcore/str.rs
src/libcore/str.rs
+124
-250
未找到文件。
src/libcore/core.rc
浏览文件 @
4b7d4cd0
...
...
@@ -169,7 +169,6 @@ mod char;
mod float;
mod f32;
mod f64;
#[legacy_exports]
mod str;
#[legacy_exports]
mod ptr;
...
...
src/libcore/str.rs
浏览文件 @
4b7d4cd0
...
...
@@ -15,115 +15,6 @@
use
io
::
WriterUtil
;
use
to_str
::
ToStr
;
export
// Creating a string
from_bytes
,
from_byte
,
from_slice
,
from_char
,
from_chars
,
append
,
concat
,
connect
,
// Reinterpretation
as_bytes
,
as_bytes_slice
,
as_buf
,
as_c_str
,
// Adding things to and removing things from a string
push_str_no_overallocate
,
push_str
,
push_char
,
pop_char
,
shift_char
,
view_shift_char
,
unshift_char
,
trim_left
,
trim_right
,
trim
,
trim_left_chars
,
trim_right_chars
,
trim_chars
,
// Transforming strings
to_bytes
,
byte_slice
,
chars
,
substr
,
slice
,
view
,
split
,
splitn
,
split_nonempty
,
split_char
,
splitn_char
,
split_char_nonempty
,
split_str
,
split_str_nonempty
,
lines
,
lines_any
,
words
,
to_lower
,
to_upper
,
replace
,
// Comparing strings
eq
,
eq_slice
,
le
,
hash
,
// Iterating through strings
all
,
any
,
all_between
,
any_between
,
map
,
each
,
eachi
,
each_char
,
each_chari
,
bytes_each
,
chars_each
,
split_char_each
,
splitn_char_each
,
words_each
,
lines_each
,
// Searching
find
,
find_from
,
find_between
,
rfind
,
rfind_from
,
rfind_between
,
find_char
,
find_char_from
,
find_char_between
,
rfind_char
,
rfind_char_from
,
rfind_char_between
,
find_str
,
find_str_from
,
find_str_between
,
contains
,
contains_char
,
starts_with
,
ends_with
,
// String properties
is_ascii
,
is_empty
,
is_not_empty
,
is_whitespace
,
len
,
char_len
,
// Misc
is_utf8
,
is_utf16
,
to_utf16
,
from_utf16
,
utf16_chars
,
count_chars
,
count_bytes
,
utf8_char_width
,
char_range_at
,
is_char_boundary
,
char_at
,
reserve
,
reserve_at_least
,
capacity
,
escape_default
,
escape_unicode
,
raw
,
extensions
,
StrSlice
,
UniqueStr
,
traits
;
/*
Section: Creating a string
*/
...
...
@@ -135,13 +26,13 @@
*
* Fails if invalid UTF-8
*/
pure
fn
from_bytes
(
vv
:
&
[
const
u8
])
->
~
str
{
pu
b
pu
re
fn
from_bytes
(
vv
:
&
[
const
u8
])
->
~
str
{
assert
is_utf8
(
vv
);
return
unsafe
{
raw
::
from_bytes
(
vv
)
};
}
/// Copy a slice into a new unique str
pure
fn
from_slice
(
s
:
&
str
)
->
~
str
{
pu
b
pu
re
fn
from_slice
(
s
:
&
str
)
->
~
str
{
unsafe
{
raw
::
slice_bytes
(
s
,
0
,
len
(
s
))
}
}
...
...
@@ -152,13 +43,13 @@
*
* Fails if invalid UTF-8
*/
pure
fn
from_byte
(
b
:
u8
)
->
~
str
{
pu
b
pu
re
fn
from_byte
(
b
:
u8
)
->
~
str
{
assert
b
<
128u8
;
unsafe
{
::
cast
::
transmute
(
~
[
b
,
0u8
])
}
}
/// Appends a character at the end of a string
fn
push_char
(
s
:
&
const
~
str
,
ch
:
char
)
{
pub
fn
push_char
(
s
:
&
const
~
str
,
ch
:
char
)
{
unsafe
{
let
code
=
ch
as
uint
;
let
nb
=
if
code
<
max_one_b
{
1u
}
...
...
@@ -229,14 +120,14 @@ fn push_char(s: &const ~str, ch: char) {
}
/// Convert a char to a string
pure
fn
from_char
(
ch
:
char
)
->
~
str
{
pu
b
pu
re
fn
from_char
(
ch
:
char
)
->
~
str
{
let
mut
buf
=
~
""
;
unsafe
{
push_char
(
&
mut
buf
,
ch
);
}
move
buf
}
/// Convert a vector of chars to a string
pure
fn
from_chars
(
chs
:
&
[
char
])
->
~
str
{
pu
b
pu
re
fn
from_chars
(
chs
:
&
[
char
])
->
~
str
{
let
mut
buf
=
~
""
;
unsafe
{
reserve
(
&
mut
buf
,
chs
.len
());
...
...
@@ -249,7 +140,7 @@ fn push_char(s: &const ~str, ch: char) {
/// Appends a string slice to the back of a string, without overallocating
#[inline(always)]
fn
push_str_no_overallocate
(
lhs
:
&
const
~
str
,
rhs
:
&
str
)
{
pub
fn
push_str_no_overallocate
(
lhs
:
&
const
~
str
,
rhs
:
&
str
)
{
unsafe
{
let
llen
=
lhs
.len
();
let
rlen
=
rhs
.len
();
...
...
@@ -266,7 +157,7 @@ fn push_str_no_overallocate(lhs: &const ~str, rhs: &str) {
}
/// Appends a string slice to the back of a string
#[inline(always)]
fn
push_str
(
lhs
:
&
const
~
str
,
rhs
:
&
str
)
{
pub
fn
push_str
(
lhs
:
&
const
~
str
,
rhs
:
&
str
)
{
unsafe
{
let
llen
=
lhs
.len
();
let
rlen
=
rhs
.len
();
...
...
@@ -284,7 +175,7 @@ fn push_str(lhs: &const ~str, rhs: &str) {
/// Concatenate two strings together
#[inline(always)]
pure
fn
append
(
+
lhs
:
~
str
,
rhs
:
&
str
)
->
~
str
{
pu
b
pu
re
fn
append
(
+
lhs
:
~
str
,
rhs
:
&
str
)
->
~
str
{
let
mut
v
<-
lhs
;
unsafe
{
push_str_no_overallocate
(
&
mut
v
,
rhs
);
...
...
@@ -294,7 +185,7 @@ fn push_str(lhs: &const ~str, rhs: &str) {
/// Concatenate a vector of strings
pure
fn
concat
(
v
:
&
[
~
str
])
->
~
str
{
pu
b
pu
re
fn
concat
(
v
:
&
[
~
str
])
->
~
str
{
let
mut
s
:
~
str
=
~
""
;
for
vec
::
each
(
v
)
|
ss
|
{
unsafe
{
push_str
(
&
mut
s
,
*
ss
)
};
...
...
@@ -303,7 +194,7 @@ fn push_str(lhs: &const ~str, rhs: &str) {
}
/// Concatenate a vector of strings, placing a given separator between each
pure
fn
connect
(
v
:
&
[
~
str
],
sep
:
&
str
)
->
~
str
{
pu
b
pu
re
fn
connect
(
v
:
&
[
~
str
],
sep
:
&
str
)
->
~
str
{
let
mut
s
=
~
""
,
first
=
true
;
for
vec
::
each
(
v
)
|
ss
|
{
if
first
{
first
=
false
;
}
else
{
unsafe
{
push_str
(
&
mut
s
,
sep
);
}
}
...
...
@@ -323,7 +214,7 @@ fn push_str(lhs: &const ~str, rhs: &str) {
*
* If the string does not contain any characters
*/
fn
pop_char
(
s
:
&
const
~
str
)
->
char
{
pub
fn
pop_char
(
s
:
&
const
~
str
)
->
char
{
let
end
=
len
(
*
s
);
assert
end
>
0u
;
let
{
ch
,
prev
}
=
char_range_at_reverse
(
*
s
,
end
);
...
...
@@ -338,7 +229,7 @@ fn pop_char(s: &const ~str) -> char {
*
* If the string does not contain any characters
*/
fn
shift_char
(
s
:
&
mut
~
str
)
->
char
{
pub
fn
shift_char
(
s
:
&
mut
~
str
)
->
char
{
let
{
ch
,
next
}
=
char_range_at
(
*
s
,
0u
);
*
s
=
unsafe
{
raw
::
slice_bytes
(
*
s
,
next
,
len
(
*
s
))
};
return
ch
;
...
...
@@ -354,14 +245,14 @@ fn shift_char(s: &mut ~str) -> char {
* If the string does not contain any characters
*/
#[inline]
fn
view_shift_char
(
s
:
&
a
/
str
)
->
(
char
,
&
a
/
str
)
{
pub
fn
view_shift_char
(
s
:
&
a
/
str
)
->
(
char
,
&
a
/
str
)
{
let
{
ch
,
next
}
=
char_range_at
(
s
,
0u
);
let
next_s
=
unsafe
{
raw
::
view_bytes
(
s
,
next
,
len
(
s
))
};
return
(
ch
,
next_s
);
}
/// Prepend a char to a string
fn
unshift_char
(
s
:
&
mut
~
str
,
ch
:
char
)
{
pub
fn
unshift_char
(
s
:
&
mut
~
str
,
ch
:
char
)
{
*
s
=
from_char
(
ch
)
+
*
s
;
}
...
...
@@ -374,7 +265,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
* * chars_to_trim - A vector of chars
*
*/
pure
fn
trim_left_chars
(
s
:
&
str
,
chars_to_trim
:
&
[
char
])
->
~
str
{
pu
b
pu
re
fn
trim_left_chars
(
s
:
&
str
,
chars_to_trim
:
&
[
char
])
->
~
str
{
if
chars_to_trim
.is_empty
()
{
return
from_slice
(
s
);
}
match
find
(
s
,
|
c
|
!
chars_to_trim
.contains
(
&
c
))
{
...
...
@@ -392,7 +283,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
* * chars_to_trim - A vector of chars
*
*/
pure
fn
trim_right_chars
(
s
:
&
str
,
chars_to_trim
:
&
[
char
])
->
~
str
{
pu
b
pu
re
fn
trim_right_chars
(
s
:
&
str
,
chars_to_trim
:
&
[
char
])
->
~
str
{
if
chars_to_trim
.is_empty
()
{
return
str
::
from_slice
(
s
);
}
match
rfind
(
s
,
|
c
|
!
chars_to_trim
.contains
(
&
c
))
{
...
...
@@ -413,12 +304,12 @@ fn unshift_char(s: &mut ~str, ch: char) {
* * chars_to_trim - A vector of chars
*
*/
pure
fn
trim_chars
(
s
:
&
str
,
chars_to_trim
:
&
[
char
])
->
~
str
{
pu
b
pu
re
fn
trim_chars
(
s
:
&
str
,
chars_to_trim
:
&
[
char
])
->
~
str
{
trim_left_chars
(
trim_right_chars
(
s
,
chars_to_trim
),
chars_to_trim
)
}
/// Returns a string with leading whitespace removed
pure
fn
trim_left
(
s
:
&
str
)
->
~
str
{
pu
b
pu
re
fn
trim_left
(
s
:
&
str
)
->
~
str
{
match
find
(
s
,
|
c
|
!
char
::
is_whitespace
(
c
))
{
None
=>
~
""
,
Some
(
first
)
=>
unsafe
{
raw
::
slice_bytes
(
s
,
first
,
len
(
s
))
}
...
...
@@ -426,7 +317,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
}
/// Returns a string with trailing whitespace removed
pure
fn
trim_right
(
s
:
&
str
)
->
~
str
{
pu
b
pu
re
fn
trim_right
(
s
:
&
str
)
->
~
str
{
match
rfind
(
s
,
|
c
|
!
char
::
is_whitespace
(
c
))
{
None
=>
~
""
,
Some
(
last
)
=>
{
...
...
@@ -437,7 +328,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
}
/// Returns a string with leading and trailing whitespace removed
pure
fn
trim
(
s
:
&
str
)
->
~
str
{
trim_left
(
trim_right
(
s
))
}
pu
b
pu
re
fn
trim
(
s
:
&
str
)
->
~
str
{
trim_left
(
trim_right
(
s
))
}
/*
Section: Transforming strings
...
...
@@ -448,7 +339,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
*
* The result vector is not null-terminated.
*/
pure
fn
to_bytes
(
s
:
&
str
)
->
~
[
u8
]
unsafe
{
pu
b
pu
re
fn
to_bytes
(
s
:
&
str
)
->
~
[
u8
]
unsafe
{
let
mut
v
:
~
[
u8
]
=
::
cast
::
transmute
(
from_slice
(
s
));
vec
::
raw
::
set_len
(
&
mut
v
,
len
(
s
));
move
v
...
...
@@ -456,14 +347,14 @@ fn unshift_char(s: &mut ~str, ch: char) {
/// Work with the string as a byte slice, not including trailing null.
#[inline(always)]
pure
fn
byte_slice
<
T
>
(
s
:
&
str
,
f
:
fn
(
v
:
&
[
u8
])
->
T
)
->
T
{
pu
b
pu
re
fn
byte_slice
<
T
>
(
s
:
&
str
,
f
:
fn
(
v
:
&
[
u8
])
->
T
)
->
T
{
do
as_buf
(
s
)
|
p
,
n
|
{
unsafe
{
vec
::
raw
::
form_slice
(
p
,
n
-
1u
,
f
)
}
}
}
/// Convert a string to a vector of characters
pure
fn
chars
(
s
:
&
str
)
->
~
[
char
]
{
pu
b
pu
re
fn
chars
(
s
:
&
str
)
->
~
[
char
]
{
let
mut
buf
=
~
[],
i
=
0
;
let
len
=
len
(
s
);
while
i
<
len
{
...
...
@@ -480,7 +371,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
* Returns a string containing `n` characters starting at byte offset
* `begin`.
*/
pure
fn
substr
(
s
:
&
str
,
begin
:
uint
,
n
:
uint
)
->
~
str
{
pu
b
pu
re
fn
substr
(
s
:
&
str
,
begin
:
uint
,
n
:
uint
)
->
~
str
{
slice
(
s
,
begin
,
begin
+
count_bytes
(
s
,
begin
,
n
))
}
...
...
@@ -490,7 +381,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
* Fails when `begin` and `end` do not point to valid characters or
* beyond the last character of the string
*/
pure
fn
slice
(
s
:
&
str
,
begin
:
uint
,
end
:
uint
)
->
~
str
{
pu
b
pu
re
fn
slice
(
s
:
&
str
,
begin
:
uint
,
end
:
uint
)
->
~
str
{
assert
is_char_boundary
(
s
,
begin
);
assert
is_char_boundary
(
s
,
end
);
unsafe
{
raw
::
slice_bytes
(
s
,
begin
,
end
)
}
...
...
@@ -502,14 +393,14 @@ fn unshift_char(s: &mut ~str, ch: char) {
* Fails when `begin` and `end` do not point to valid characters or beyond
* the last character of the string
*/
pure
fn
view
(
s
:
&
a
/
str
,
begin
:
uint
,
end
:
uint
)
->
&
a
/
str
{
pu
b
pu
re
fn
view
(
s
:
&
a
/
str
,
begin
:
uint
,
end
:
uint
)
->
&
a
/
str
{
assert
is_char_boundary
(
s
,
begin
);
assert
is_char_boundary
(
s
,
end
);
unsafe
{
raw
::
view_bytes
(
s
,
begin
,
end
)
}
}
/// Splits a string into substrings at each occurrence of a given character
pure
fn
split_char
(
s
:
&
str
,
sep
:
char
)
->
~
[
~
str
]
{
pu
b
pu
re
fn
split_char
(
s
:
&
str
,
sep
:
char
)
->
~
[
~
str
]
{
split_char_inner
(
s
,
sep
,
len
(
s
),
true
)
}
...
...
@@ -519,12 +410,12 @@ fn unshift_char(s: &mut ~str, ch: char) {
*
* The byte must be a valid UTF-8/ASCII byte
*/
pure
fn
splitn_char
(
s
:
&
str
,
sep
:
char
,
count
:
uint
)
->
~
[
~
str
]
{
pu
b
pu
re
fn
splitn_char
(
s
:
&
str
,
sep
:
char
,
count
:
uint
)
->
~
[
~
str
]
{
split_char_inner
(
s
,
sep
,
count
,
true
)
}
/// Like `split_char`, but omits empty strings from the returned vector
pure
fn
split_char_nonempty
(
s
:
&
str
,
sep
:
char
)
->
~
[
~
str
]
{
pu
b
pu
re
fn
split_char_nonempty
(
s
:
&
str
,
sep
:
char
)
->
~
[
~
str
]
{
split_char_inner
(
s
,
sep
,
len
(
s
),
false
)
}
...
...
@@ -555,7 +446,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
/// Splits a string into substrings using a character function
pure
fn
split
(
s
:
&
str
,
sepfn
:
fn
(
char
)
->
bool
)
->
~
[
~
str
]
{
pu
b
pu
re
fn
split
(
s
:
&
str
,
sepfn
:
fn
(
char
)
->
bool
)
->
~
[
~
str
]
{
split_inner
(
s
,
sepfn
,
len
(
s
),
true
)
}
...
...
@@ -563,12 +454,12 @@ fn unshift_char(s: &mut ~str, ch: char) {
* Splits a string into substrings using a character function, cutting at
* most `count` times.
*/
pure
fn
splitn
(
s
:
&
str
,
sepfn
:
fn
(
char
)
->
bool
,
count
:
uint
)
->
~
[
~
str
]
{
pu
b
pu
re
fn
splitn
(
s
:
&
str
,
sepfn
:
fn
(
char
)
->
bool
,
count
:
uint
)
->
~
[
~
str
]
{
split_inner
(
s
,
sepfn
,
count
,
true
)
}
/// Like `split`, but omits empty strings from the returned vector
pure
fn
split_nonempty
(
s
:
&
str
,
sepfn
:
fn
(
char
)
->
bool
)
->
~
[
~
str
]
{
pu
b
pu
re
fn
split_nonempty
(
s
:
&
str
,
sepfn
:
fn
(
char
)
->
bool
)
->
~
[
~
str
]
{
split_inner
(
s
,
sepfn
,
len
(
s
),
false
)
}
...
...
@@ -639,7 +530,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
* assert ["", "XXX", "YYY", ""] == split_str(".XXX.YYY.", ".")
* ~~~
*/
pure
fn
split_str
(
s
:
&
a
/
str
,
sep
:
&
b
/
str
)
->
~
[
~
str
]
{
pu
b
pu
re
fn
split_str
(
s
:
&
a
/
str
,
sep
:
&
b
/
str
)
->
~
[
~
str
]
{
let
mut
result
=
~
[];
do
iter_between_matches
(
s
,
sep
)
|
from
,
to
|
{
unsafe
{
result
.push
(
raw
::
slice_bytes
(
s
,
from
,
to
));
}
...
...
@@ -647,7 +538,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
move
result
}
pure
fn
split_str_nonempty
(
s
:
&
a
/
str
,
sep
:
&
b
/
str
)
->
~
[
~
str
]
{
pu
b
pu
re
fn
split_str_nonempty
(
s
:
&
a
/
str
,
sep
:
&
b
/
str
)
->
~
[
~
str
]
{
let
mut
result
=
~
[];
do
iter_between_matches
(
s
,
sep
)
|
from
,
to
|
{
if
to
>
from
{
...
...
@@ -660,13 +551,13 @@ fn unshift_char(s: &mut ~str, ch: char) {
/**
* Splits a string into a vector of the substrings separated by LF ('\n')
*/
pure
fn
lines
(
s
:
&
str
)
->
~
[
~
str
]
{
split_char
(
s
,
'\n'
)
}
pu
b
pu
re
fn
lines
(
s
:
&
str
)
->
~
[
~
str
]
{
split_char
(
s
,
'\n'
)
}
/**
* Splits a string into a vector of the substrings separated by LF ('\n')
* and/or CR LF ("\r\n")
*/
pure
fn
lines_any
(
s
:
&
str
)
->
~
[
~
str
]
{
pu
b
pu
re
fn
lines_any
(
s
:
&
str
)
->
~
[
~
str
]
{
vec
::
map
(
lines
(
s
),
|
s
|
{
let
l
=
len
(
*
s
);
let
mut
cp
=
copy
*
s
;
...
...
@@ -678,19 +569,19 @@ fn unshift_char(s: &mut ~str, ch: char) {
}
/// Splits a string into a vector of the substrings separated by whitespace
pure
fn
words
(
s
:
&
str
)
->
~
[
~
str
]
{
pu
b
pu
re
fn
words
(
s
:
&
str
)
->
~
[
~
str
]
{
split_nonempty
(
s
,
|
c
|
char
::
is_whitespace
(
c
))
}
/// Convert a string to lowercase. ASCII only
pure
fn
to_lower
(
s
:
&
str
)
->
~
str
{
pu
b
pu
re
fn
to_lower
(
s
:
&
str
)
->
~
str
{
map
(
s
,
|
c
|
unsafe
{(
libc
::
tolower
(
c
as
libc
::
c_char
))
as
char
}
)
}
/// Convert a string to uppercase. ASCII only
pure
fn
to_upper
(
s
:
&
str
)
->
~
str
{
pu
b
pu
re
fn
to_upper
(
s
:
&
str
)
->
~
str
{
map
(
s
,
|
c
|
unsafe
{(
libc
::
toupper
(
c
as
libc
::
c_char
))
as
char
}
)
...
...
@@ -709,7 +600,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
*
* The original string with all occurances of `from` replaced with `to`
*/
pure
fn
replace
(
s
:
&
str
,
from
:
&
str
,
to
:
&
str
)
->
~
str
{
pu
b
pu
re
fn
replace
(
s
:
&
str
,
from
:
&
str
,
to
:
&
str
)
->
~
str
{
let
mut
result
=
~
""
,
first
=
true
;
do
iter_between_matches
(
s
,
from
)
|
start
,
end
|
{
if
first
{
...
...
@@ -729,7 +620,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
/// Bytewise slice equality
#[cfg(notest)]
#[lang=
"str_eq"
]
pure
fn
eq_slice
(
a
:
&
str
,
b
:
&
str
)
->
bool
{
pu
b
pu
re
fn
eq_slice
(
a
:
&
str
,
b
:
&
str
)
->
bool
{
do
as_buf
(
a
)
|
ap
,
alen
|
{
do
as_buf
(
b
)
|
bp
,
blen
|
{
if
(
alen
!=
blen
)
{
false
}
...
...
@@ -745,7 +636,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
}
#[cfg(test)]
pure
fn
eq_slice
(
a
:
&
str
,
b
:
&
str
)
->
bool
{
pu
b
pu
re
fn
eq_slice
(
a
:
&
str
,
b
:
&
str
)
->
bool
{
do
as_buf
(
a
)
|
ap
,
alen
|
{
do
as_buf
(
b
)
|
bp
,
blen
|
{
if
(
alen
!=
blen
)
{
false
}
...
...
@@ -763,12 +654,12 @@ fn unshift_char(s: &mut ~str, ch: char) {
/// Bytewise string equality
#[cfg(notest)]
#[lang=
"uniq_str_eq"
]
pure
fn
eq
(
a
:
&~
str
,
b
:
&~
str
)
->
bool
{
pu
b
pu
re
fn
eq
(
a
:
&~
str
,
b
:
&~
str
)
->
bool
{
eq_slice
(
*
a
,
*
b
)
}
#[cfg(test)]
pure
fn
eq
(
a
:
&~
str
,
b
:
&~
str
)
->
bool
{
pu
b
pu
re
fn
eq
(
a
:
&~
str
,
b
:
&~
str
)
->
bool
{
eq_slice
(
*
a
,
*
b
)
}
...
...
@@ -789,7 +680,7 @@ fn unshift_char(s: &mut ~str, ch: char) {
}
/// Bytewise less than or equal
pure
fn
le
(
a
:
&
str
,
b
:
&
str
)
->
bool
{
pu
b
pu
re
fn
le
(
a
:
&
str
,
b
:
&
str
)
->
bool
{
!
lt
(
b
,
a
)
}
...
...
@@ -871,7 +762,7 @@ impl @str : Ord {
* Return true if a predicate matches all characters or if the string
* contains no characters
*/
pure
fn
all
(
s
:
&
str
,
it
:
fn
(
char
)
->
bool
)
->
bool
{
pu
b
pu
re
fn
all
(
s
:
&
str
,
it
:
fn
(
char
)
->
bool
)
->
bool
{
all_between
(
s
,
0u
,
len
(
s
),
it
)
}
...
...
@@ -879,12 +770,12 @@ impl @str : Ord {
* Return true if a predicate matches any character (and false if it
* matches none or there are no characters)
*/
pure
fn
any
(
ss
:
&
str
,
pred
:
fn
(
char
)
->
bool
)
->
bool
{
pu
b
pu
re
fn
any
(
ss
:
&
str
,
pred
:
fn
(
char
)
->
bool
)
->
bool
{
!
all
(
ss
,
|
cc
|
!
pred
(
cc
))
}
/// Apply a function to each character
pure
fn
map
(
ss
:
&
str
,
ff
:
fn
(
char
)
->
char
)
->
~
str
{
pu
b
pu
re
fn
map
(
ss
:
&
str
,
ff
:
fn
(
char
)
->
char
)
->
~
str
{
let
mut
result
=
~
""
;
unsafe
{
reserve
(
&
mut
result
,
len
(
ss
));
...
...
@@ -896,7 +787,7 @@ impl @str : Ord {
}
/// Iterate over the bytes in a string
pure
fn
bytes_each
(
ss
:
&
str
,
it
:
fn
(
u8
)
->
bool
)
{
pu
b
pu
re
fn
bytes_each
(
ss
:
&
str
,
it
:
fn
(
u8
)
->
bool
)
{
let
mut
pos
=
0u
;
let
len
=
len
(
ss
);
...
...
@@ -908,13 +799,13 @@ impl @str : Ord {
/// Iterate over the bytes in a string
#[inline(always)]
pure
fn
each
(
s
:
&
str
,
it
:
fn
(
u8
)
->
bool
)
{
pu
b
pu
re
fn
each
(
s
:
&
str
,
it
:
fn
(
u8
)
->
bool
)
{
eachi
(
s
,
|
_
i
,
b
|
it
(
b
)
)
}
/// Iterate over the bytes in a string, with indices
#[inline(always)]
pure
fn
eachi
(
s
:
&
str
,
it
:
fn
(
uint
,
u8
)
->
bool
)
{
pu
b
pu
re
fn
eachi
(
s
:
&
str
,
it
:
fn
(
uint
,
u8
)
->
bool
)
{
let
mut
i
=
0u
,
l
=
len
(
s
);
while
(
i
<
l
)
{
if
!
it
(
i
,
s
[
i
])
{
break
;
}
...
...
@@ -924,13 +815,13 @@ impl @str : Ord {
/// Iterates over the chars in a string
#[inline(always)]
pure
fn
each_char
(
s
:
&
str
,
it
:
fn
(
char
)
->
bool
)
{
pu
b
pu
re
fn
each_char
(
s
:
&
str
,
it
:
fn
(
char
)
->
bool
)
{
each_chari
(
s
,
|
_
i
,
c
|
it
(
c
))
}
/// Iterates over the chars in a string, with indices
#[inline(always)]
pure
fn
each_chari
(
s
:
&
str
,
it
:
fn
(
uint
,
char
)
->
bool
)
{
pu
b
pu
re
fn
each_chari
(
s
:
&
str
,
it
:
fn
(
uint
,
char
)
->
bool
)
{
let
mut
pos
=
0u
,
ch_pos
=
0u
;
let
len
=
len
(
s
);
while
pos
<
len
{
...
...
@@ -942,7 +833,7 @@ impl @str : Ord {
}
/// Iterate over the characters in a string
pure
fn
chars_each
(
s
:
&
str
,
it
:
fn
(
char
)
->
bool
)
{
pu
b
pu
re
fn
chars_each
(
s
:
&
str
,
it
:
fn
(
char
)
->
bool
)
{
let
mut
pos
=
0u
;
let
len
=
len
(
s
);
while
(
pos
<
len
)
{
...
...
@@ -953,7 +844,7 @@ impl @str : Ord {
}
/// Apply a function to each substring after splitting by character
pure
fn
split_char_each
(
ss
:
&
str
,
cc
:
char
,
ff
:
fn
(
v
:
&
str
)
->
bool
)
{
pu
b
pu
re
fn
split_char_each
(
ss
:
&
str
,
cc
:
char
,
ff
:
fn
(
v
:
&
str
)
->
bool
)
{
vec
::
each
(
split_char
(
ss
,
cc
),
|
s
|
ff
(
*
s
))
}
...
...
@@ -961,20 +852,20 @@ impl @str : Ord {
* Apply a function to each substring after splitting by character, up to
* `count` times
*/
pure
fn
splitn_char_each
(
ss
:
&
str
,
sep
:
char
,
count
:
uint
,
pu
b
pu
re
fn
splitn_char_each
(
ss
:
&
str
,
sep
:
char
,
count
:
uint
,
ff
:
fn
(
v
:
&
str
)
->
bool
)
{
vec
::
each
(
splitn_char
(
ss
,
sep
,
count
),
|
s
|
ff
(
*
s
))
}
/// Apply a function to each word
pure
fn
words_each
(
ss
:
&
str
,
ff
:
fn
(
v
:
&
str
)
->
bool
)
{
pu
b
pu
re
fn
words_each
(
ss
:
&
str
,
ff
:
fn
(
v
:
&
str
)
->
bool
)
{
vec
::
each
(
words
(
ss
),
|
s
|
ff
(
*
s
))
}
/**
* Apply a function to each line (by '\n')
*/
pure
fn
lines_each
(
ss
:
&
str
,
ff
:
fn
(
v
:
&
str
)
->
bool
)
{
pu
b
pu
re
fn
lines_each
(
ss
:
&
str
,
ff
:
fn
(
v
:
&
str
)
->
bool
)
{
vec
::
each
(
lines
(
ss
),
|
s
|
ff
(
*
s
))
}
...
...
@@ -995,7 +886,7 @@ impl @str : Ord {
* An `option` containing the byte index of the first matching character
* or `none` if there is no match
*/
pure
fn
find_char
(
s
:
&
str
,
c
:
char
)
->
Option
<
uint
>
{
pu
b
pu
re
fn
find_char
(
s
:
&
str
,
c
:
char
)
->
Option
<
uint
>
{
find_char_between
(
s
,
c
,
0u
,
len
(
s
))
}
...
...
@@ -1019,7 +910,7 @@ impl @str : Ord {
* `start` must be less than or equal to `len(s)`. `start` must be the
* index of a character boundary, as defined by `is_char_boundary`.
*/
pure
fn
find_char_from
(
s
:
&
str
,
c
:
char
,
start
:
uint
)
->
Option
<
uint
>
{
pu
b
pu
re
fn
find_char_from
(
s
:
&
str
,
c
:
char
,
start
:
uint
)
->
Option
<
uint
>
{
find_char_between
(
s
,
c
,
start
,
len
(
s
))
}
...
...
@@ -1044,7 +935,7 @@ impl @str : Ord {
* or equal to `len(s)`. `start` must be the index of a character boundary,
* as defined by `is_char_boundary`.
*/
pure
fn
find_char_between
(
s
:
&
str
,
c
:
char
,
start
:
uint
,
end
:
uint
)
pu
b
pu
re
fn
find_char_between
(
s
:
&
str
,
c
:
char
,
start
:
uint
,
end
:
uint
)
->
Option
<
uint
>
{
if
c
<
128u
as
char
{
assert
start
<=
end
;
...
...
@@ -1074,7 +965,7 @@ impl @str : Ord {
* An `option` containing the byte index of the last matching character
* or `none` if there is no match
*/
pure
fn
rfind_char
(
s
:
&
str
,
c
:
char
)
->
Option
<
uint
>
{
pu
b
pu
re
fn
rfind_char
(
s
:
&
str
,
c
:
char
)
->
Option
<
uint
>
{
rfind_char_between
(
s
,
c
,
len
(
s
),
0u
)
}
...
...
@@ -1098,7 +989,7 @@ impl @str : Ord {
* `start` must be less than or equal to `len(s)`. `start` must be
* the index of a character boundary, as defined by `is_char_boundary`.
*/
pure
fn
rfind_char_from
(
s
:
&
str
,
c
:
char
,
start
:
uint
)
->
Option
<
uint
>
{
pu
b
pu
re
fn
rfind_char_from
(
s
:
&
str
,
c
:
char
,
start
:
uint
)
->
Option
<
uint
>
{
rfind_char_between
(
s
,
c
,
start
,
0u
)
}
...
...
@@ -1123,7 +1014,7 @@ impl @str : Ord {
* or equal to `len(s)`. `start` must be the index of a character boundary,
* as defined by `is_char_boundary`.
*/
pure
fn
rfind_char_between
(
s
:
&
str
,
c
:
char
,
start
:
uint
,
end
:
uint
)
pu
b
pu
re
fn
rfind_char_between
(
s
:
&
str
,
c
:
char
,
start
:
uint
,
end
:
uint
)
->
Option
<
uint
>
{
if
c
<
128u
as
char
{
assert
start
>=
end
;
...
...
@@ -1154,7 +1045,7 @@ impl @str : Ord {
* An `option` containing the byte index of the first matching character
* or `none` if there is no match
*/
pure
fn
find
(
s
:
&
str
,
f
:
fn
(
char
)
->
bool
)
->
Option
<
uint
>
{
pu
b
pu
re
fn
find
(
s
:
&
str
,
f
:
fn
(
char
)
->
bool
)
->
Option
<
uint
>
{
find_between
(
s
,
0u
,
len
(
s
),
f
)
}
...
...
@@ -1178,7 +1069,7 @@ impl @str : Ord {
* `start` must be less than or equal to `len(s)`. `start` must be the
* index of a character boundary, as defined by `is_char_boundary`.
*/
pure
fn
find_from
(
s
:
&
str
,
start
:
uint
,
f
:
fn
(
char
)
pu
b
pu
re
fn
find_from
(
s
:
&
str
,
start
:
uint
,
f
:
fn
(
char
)
->
bool
)
->
Option
<
uint
>
{
find_between
(
s
,
start
,
len
(
s
),
f
)
}
...
...
@@ -1205,7 +1096,7 @@ impl @str : Ord {
* or equal to `len(s)`. `start` must be the index of a character
* boundary, as defined by `is_char_boundary`.
*/
pure
fn
find_between
(
s
:
&
str
,
start
:
uint
,
end
:
uint
,
f
:
fn
(
char
)
->
bool
)
pu
b
pu
re
fn
find_between
(
s
:
&
str
,
start
:
uint
,
end
:
uint
,
f
:
fn
(
char
)
->
bool
)
->
Option
<
uint
>
{
assert
start
<=
end
;
assert
end
<=
len
(
s
);
...
...
@@ -1233,7 +1124,7 @@ impl @str : Ord {
* An option containing the byte index of the last matching character
* or `none` if there is no match
*/
pure
fn
rfind
(
s
:
&
str
,
f
:
fn
(
char
)
->
bool
)
->
Option
<
uint
>
{
pu
b
pu
re
fn
rfind
(
s
:
&
str
,
f
:
fn
(
char
)
->
bool
)
->
Option
<
uint
>
{
rfind_between
(
s
,
len
(
s
),
0u
,
f
)
}
...
...
@@ -1257,7 +1148,7 @@ impl @str : Ord {
* `start` must be less than or equal to `len(s)', `start` must be the
* index of a character boundary, as defined by `is_char_boundary`
*/
pure
fn
rfind_from
(
s
:
&
str
,
start
:
uint
,
f
:
fn
(
char
)
->
bool
)
pu
b
pu
re
fn
rfind_from
(
s
:
&
str
,
start
:
uint
,
f
:
fn
(
char
)
->
bool
)
->
Option
<
uint
>
{
rfind_between
(
s
,
start
,
0u
,
f
)
}
...
...
@@ -1284,7 +1175,7 @@ impl @str : Ord {
* than or equal to `len(s)`. `start` must be the index of a character
* boundary, as defined by `is_char_boundary`
*/
pure
fn
rfind_between
(
s
:
&
str
,
start
:
uint
,
end
:
uint
,
f
:
fn
(
char
)
->
bool
)
pu
b
pu
re
fn
rfind_between
(
s
:
&
str
,
start
:
uint
,
end
:
uint
,
f
:
fn
(
char
)
->
bool
)
->
Option
<
uint
>
{
assert
start
>=
end
;
assert
start
<=
len
(
s
);
...
...
@@ -1318,7 +1209,7 @@ impl @str : Ord {
* An `option` containing the byte index of the first matching substring
* or `none` if there is no match
*/
pure
fn
find_str
(
haystack
:
&
a
/
str
,
needle
:
&
b
/
str
)
->
Option
<
uint
>
{
pu
b
pu
re
fn
find_str
(
haystack
:
&
a
/
str
,
needle
:
&
b
/
str
)
->
Option
<
uint
>
{
find_str_between
(
haystack
,
needle
,
0u
,
len
(
haystack
))
}
...
...
@@ -1341,7 +1232,7 @@ impl @str : Ord {
*
* `start` must be less than or equal to `len(s)`
*/
pure
fn
find_str_from
(
haystack
:
&
a
/
str
,
needle
:
&
b
/
str
,
start
:
uint
)
pu
b
pu
re
fn
find_str_from
(
haystack
:
&
a
/
str
,
needle
:
&
b
/
str
,
start
:
uint
)
->
Option
<
uint
>
{
find_str_between
(
haystack
,
needle
,
start
,
len
(
haystack
))
}
...
...
@@ -1366,7 +1257,7 @@ impl @str : Ord {
* `start` must be less than or equal to `end` and `end` must be less than
* or equal to `len(s)`.
*/
pure
fn
find_str_between
(
haystack
:
&
a
/
str
,
needle
:
&
b
/
str
,
start
:
uint
,
pu
b
pu
re
fn
find_str_between
(
haystack
:
&
a
/
str
,
needle
:
&
b
/
str
,
start
:
uint
,
end
:
uint
)
->
Option
<
uint
>
{
// See Issue #1932 for why this is a naive search
...
...
@@ -1392,7 +1283,7 @@ impl @str : Ord {
* * haystack - The string to look in
* * needle - The string to look for
*/
pure
fn
contains
(
haystack
:
&
a
/
str
,
needle
:
&
b
/
str
)
->
bool
{
pu
b
pu
re
fn
contains
(
haystack
:
&
a
/
str
,
needle
:
&
b
/
str
)
->
bool
{
find_str
(
haystack
,
needle
)
.is_some
()
}
...
...
@@ -1404,7 +1295,7 @@ impl @str : Ord {
* * haystack - The string to look in
* * needle - The char to look for
*/
pure
fn
contains_char
(
haystack
:
&
str
,
needle
:
char
)
->
bool
{
pu
b
pu
re
fn
contains_char
(
haystack
:
&
str
,
needle
:
char
)
->
bool
{
find_char
(
haystack
,
needle
)
.is_some
()
}
...
...
@@ -1416,7 +1307,7 @@ impl @str : Ord {
* * haystack - The string to look in
* * needle - The string to look for
*/
pure
fn
starts_with
(
haystack
:
&
a
/
str
,
needle
:
&
b
/
str
)
->
bool
{
pu
b
pu
re
fn
starts_with
(
haystack
:
&
a
/
str
,
needle
:
&
b
/
str
)
->
bool
{
let
haystack_len
=
len
(
haystack
),
needle_len
=
len
(
needle
);
if
needle_len
==
0u
{
true
}
else
if
needle_len
>
haystack_len
{
false
}
...
...
@@ -1431,7 +1322,7 @@ impl @str : Ord {
* * haystack - The string to look in
* * needle - The string to look for
*/
pure
fn
ends_with
(
haystack
:
&
a
/
str
,
needle
:
&
b
/
str
)
->
bool
{
pu
b
pu
re
fn
ends_with
(
haystack
:
&
a
/
str
,
needle
:
&
b
/
str
)
->
bool
{
let
haystack_len
=
len
(
haystack
),
needle_len
=
len
(
needle
);
if
needle_len
==
0u
{
true
}
else
if
needle_len
>
haystack_len
{
false
}
...
...
@@ -1443,24 +1334,24 @@ impl @str : Ord {
*/
/// Determines if a string contains only ASCII characters
pure
fn
is_ascii
(
s
:
&
str
)
->
bool
{
pu
b
pu
re
fn
is_ascii
(
s
:
&
str
)
->
bool
{
let
mut
i
:
uint
=
len
(
s
);
while
i
>
0u
{
i
-=
1u
;
if
!
u8
::
is_ascii
(
s
[
i
])
{
return
false
;
}
}
return
true
;
}
/// Returns true if the string has length 0
pure
fn
is_empty
(
s
:
&
str
)
->
bool
{
len
(
s
)
==
0u
}
pu
b
pu
re
fn
is_empty
(
s
:
&
str
)
->
bool
{
len
(
s
)
==
0u
}
/// Returns true if the string has length greater than 0
pure
fn
is_not_empty
(
s
:
&
str
)
->
bool
{
!
is_empty
(
s
)
}
pu
b
pu
re
fn
is_not_empty
(
s
:
&
str
)
->
bool
{
!
is_empty
(
s
)
}
/**
* Returns true if the string contains only whitespace
*
* Whitespace characters are determined by `char::is_whitespace`
*/
pure
fn
is_whitespace
(
s
:
&
str
)
->
bool
{
pu
b
pu
re
fn
is_whitespace
(
s
:
&
str
)
->
bool
{
return
all
(
s
,
char
::
is_whitespace
);
}
...
...
@@ -1474,19 +1365,19 @@ fn is_alphanumeric(s: &str) -> bool {
}
/// Returns the string length/size in bytes not counting the null terminator
pure
fn
len
(
s
:
&
str
)
->
uint
{
pu
b
pu
re
fn
len
(
s
:
&
str
)
->
uint
{
do
as_buf
(
s
)
|
_
p
,
n
|
{
n
-
1u
}
}
/// Returns the number of characters that a string holds
pure
fn
char_len
(
s
:
&
str
)
->
uint
{
count_chars
(
s
,
0u
,
len
(
s
))
}
pu
b
pu
re
fn
char_len
(
s
:
&
str
)
->
uint
{
count_chars
(
s
,
0u
,
len
(
s
))
}
/*
Section: Misc
*/
/// Determines if a vector of bytes contains valid UTF-8
pure
fn
is_utf8
(
v
:
&
[
const
u8
])
->
bool
{
pu
b
pu
re
fn
is_utf8
(
v
:
&
[
const
u8
])
->
bool
{
let
mut
i
=
0u
;
let
total
=
vec
::
len
::
<
u8
>
(
v
);
while
i
<
total
{
...
...
@@ -1504,7 +1395,7 @@ fn is_alphanumeric(s: &str) -> bool {
}
/// Determines if a vector of `u16` contains valid UTF-16
pure
fn
is_utf16
(
v
:
&
[
u16
])
->
bool
{
pu
b
pu
re
fn
is_utf16
(
v
:
&
[
u16
])
->
bool
{
let
len
=
vec
::
len
(
v
);
let
mut
i
=
0u
;
while
(
i
<
len
)
{
...
...
@@ -1525,7 +1416,7 @@ fn is_alphanumeric(s: &str) -> bool {
}
/// Converts to a vector of `u16` encoded as UTF-16
pure
fn
to_utf16
(
s
:
&
str
)
->
~
[
u16
]
{
pu
b
pu
re
fn
to_utf16
(
s
:
&
str
)
->
~
[
u16
]
{
let
mut
u
=
~
[];
for
chars_each
(
s
)
|
cch
|
{
// Arithmetic with u32 literals is easier on the eyes than chars.
...
...
@@ -1547,7 +1438,7 @@ fn is_alphanumeric(s: &str) -> bool {
move
u
}
pure
fn
utf16_chars
(
v
:
&
[
u16
],
f
:
fn
(
char
))
{
pu
b
pu
re
fn
utf16_chars
(
v
:
&
[
u16
],
f
:
fn
(
char
))
{
let
len
=
vec
::
len
(
v
);
let
mut
i
=
0u
;
while
(
i
<
len
&&
v
[
i
]
!=
0u16
)
{
...
...
@@ -1572,7 +1463,7 @@ fn is_alphanumeric(s: &str) -> bool {
}
pure
fn
from_utf16
(
v
:
&
[
u16
])
->
~
str
{
pu
b
pu
re
fn
from_utf16
(
v
:
&
[
u16
])
->
~
str
{
let
mut
buf
=
~
""
;
unsafe
{
reserve
(
&
mut
buf
,
vec
::
len
(
v
));
...
...
@@ -1595,7 +1486,7 @@ fn is_alphanumeric(s: &str) -> bool {
*
* The number of Unicode characters in `s` between the given indices.
*/
pure
fn
count_chars
(
s
:
&
str
,
start
:
uint
,
end
:
uint
)
->
uint
{
pu
b
pu
re
fn
count_chars
(
s
:
&
str
,
start
:
uint
,
end
:
uint
)
->
uint
{
assert
is_char_boundary
(
s
,
start
);
assert
is_char_boundary
(
s
,
end
);
let
mut
i
=
start
,
len
=
0u
;
...
...
@@ -1608,7 +1499,7 @@ fn is_alphanumeric(s: &str) -> bool {
}
/// Counts the number of bytes taken by the `n` in `s` starting from `start`.
pure
fn
count_bytes
(
s
:
&
b
/
str
,
start
:
uint
,
n
:
uint
)
->
uint
{
pu
b
pu
re
fn
count_bytes
(
s
:
&
b
/
str
,
start
:
uint
,
n
:
uint
)
->
uint
{
assert
is_char_boundary
(
s
,
start
);
let
mut
end
=
start
,
cnt
=
n
;
let
l
=
len
(
s
);
...
...
@@ -1622,7 +1513,7 @@ fn is_alphanumeric(s: &str) -> bool {
}
/// Given a first byte, determine how many bytes are in this UTF-8 character
pure
fn
utf8_char_width
(
b
:
u8
)
->
uint
{
pu
b
pu
re
fn
utf8_char_width
(
b
:
u8
)
->
uint
{
let
byte
:
uint
=
b
as
uint
;
if
byte
<
128u
{
return
1u
;
}
// Not a valid start byte
...
...
@@ -1638,7 +1529,7 @@ fn is_alphanumeric(s: &str) -> bool {
* Returns false if the index points into the middle of a multi-byte
* character sequence.
*/
pure
fn
is_char_boundary
(
s
:
&
str
,
index
:
uint
)
->
bool
{
pu
b
pu
re
fn
is_char_boundary
(
s
:
&
str
,
index
:
uint
)
->
bool
{
if
index
==
len
(
s
)
{
return
true
;
}
let
b
=
s
[
index
];
return
b
<
128u8
||
b
>=
192u8
;
...
...
@@ -1693,7 +1584,7 @@ fn is_alphanumeric(s: &str) -> bool {
* If `i` is greater than or equal to the length of the string.
* If `i` is not the index of the beginning of a valid UTF-8 character.
*/
pure
fn
char_range_at
(
s
:
&
str
,
i
:
uint
)
->
{
ch
:
char
,
next
:
uint
}
{
pu
b
pu
re
fn
char_range_at
(
s
:
&
str
,
i
:
uint
)
->
{
ch
:
char
,
next
:
uint
}
{
let
b0
=
s
[
i
];
let
w
=
utf8_char_width
(
b0
);
assert
(
w
!=
0u
);
...
...
@@ -1716,7 +1607,7 @@ fn is_alphanumeric(s: &str) -> bool {
}
/// Pluck a character out of a string
pure
fn
char_at
(
s
:
&
str
,
i
:
uint
)
->
char
{
return
char_range_at
(
s
,
i
)
.ch
;
}
pu
b
pu
re
fn
char_at
(
s
:
&
str
,
i
:
uint
)
->
char
{
return
char_range_at
(
s
,
i
)
.ch
;
}
/**
* Given a byte position and a str, return the previous char and its position
...
...
@@ -1762,7 +1653,7 @@ fn is_alphanumeric(s: &str) -> bool {
* `true` If execution proceeded correctly, `false` if it was interrupted,
* that is if `it` returned `false` at any point.
*/
pure
fn
all_between
(
s
:
&
str
,
start
:
uint
,
end
:
uint
,
pu
b
pu
re
fn
all_between
(
s
:
&
str
,
start
:
uint
,
end
:
uint
,
it
:
fn
(
char
)
->
bool
)
->
bool
{
assert
is_char_boundary
(
s
,
start
);
let
mut
i
=
start
;
...
...
@@ -1795,7 +1686,7 @@ fn is_alphanumeric(s: &str) -> bool {
*
* `true` if `it` returns `true` for any character
*/
pure
fn
any_between
(
s
:
&
str
,
start
:
uint
,
end
:
uint
,
pu
b
pu
re
fn
any_between
(
s
:
&
str
,
start
:
uint
,
end
:
uint
,
it
:
fn
(
char
)
->
bool
)
->
bool
{
!
all_between
(
s
,
start
,
end
,
|
c
|
!
it
(
c
))
}
...
...
@@ -1827,7 +1718,7 @@ fn is_alphanumeric(s: &str) -> bool {
* let i = str::as_bytes("Hello World") { |bytes| vec::len(bytes) };
* ~~~
*/
pure
fn
as_bytes
<
T
>
(
s
:
&
const
~
str
,
f
:
fn
((
&~
[
u8
]))
->
T
)
->
T
{
pu
b
pu
re
fn
as_bytes
<
T
>
(
s
:
&
const
~
str
,
f
:
fn
((
&~
[
u8
]))
->
T
)
->
T
{
unsafe
{
let
v
:
*~
[
u8
]
=
cast
::
transmute
(
copy
s
);
f
(
&*
v
)
...
...
@@ -1839,7 +1730,7 @@ fn is_alphanumeric(s: &str) -> bool {
*
* The byte slice does not include the null terminator.
*/
pure
fn
as_bytes_slice
(
s
:
&
a
/
str
)
->
&
a
/
[
u8
]
{
pu
b
pu
re
fn
as_bytes_slice
(
s
:
&
a
/
str
)
->
&
a
/
[
u8
]
{
unsafe
{
let
(
ptr
,
len
):
(
*
u8
,
uint
)
=
::
cast
::
reinterpret_cast
(
&
s
);
let
outgoing_tuple
:
(
*
u8
,
uint
)
=
(
ptr
,
len
-
1
);
...
...
@@ -1862,7 +1753,7 @@ fn is_alphanumeric(s: &str) -> bool {
* let s = str::as_c_str("PATH", { |path| libc::getenv(path) });
* ~~~
*/
pure
fn
as_c_str
<
T
>
(
s
:
&
str
,
f
:
fn
(
*
libc
::
c_char
)
->
T
)
->
T
{
pu
b
pu
re
fn
as_c_str
<
T
>
(
s
:
&
str
,
f
:
fn
(
*
libc
::
c_char
)
->
T
)
->
T
{
do
as_buf
(
s
)
|
buf
,
len
|
{
// NB: len includes the trailing null.
assert
len
>
0
;
...
...
@@ -1884,7 +1775,7 @@ fn is_alphanumeric(s: &str) -> bool {
* to full strings, or suffixes of them.
*/
#[inline(always)]
pure
fn
as_buf
<
T
>
(
s
:
&
str
,
f
:
fn
(
*
u8
,
uint
)
->
T
)
->
T
{
pu
b
pu
re
fn
as_buf
<
T
>
(
s
:
&
str
,
f
:
fn
(
*
u8
,
uint
)
->
T
)
->
T
{
unsafe
{
let
v
:
*
(
*
u8
,
uint
)
=
::
cast
::
reinterpret_cast
(
&
ptr
::
addr_of
(
s
));
let
(
buf
,
len
)
=
*
v
;
...
...
@@ -1908,7 +1799,7 @@ fn is_alphanumeric(s: &str) -> bool {
* * s - A string
* * n - The number of bytes to reserve space for
*/
fn
reserve
(
s
:
&
const
~
str
,
n
:
uint
)
{
pub
fn
reserve
(
s
:
&
const
~
str
,
n
:
uint
)
{
unsafe
{
let
v
:
*
mut
~
[
u8
]
=
cast
::
transmute
(
copy
s
);
vec
::
reserve
(
&
mut
*
v
,
n
+
1
);
...
...
@@ -1935,7 +1826,7 @@ fn reserve(s: &const ~str, n: uint) {
* * s - A string
* * n - The number of bytes to reserve space for
*/
fn
reserve_at_least
(
s
:
&
const
~
str
,
n
:
uint
)
{
pub
fn
reserve_at_least
(
s
:
&
const
~
str
,
n
:
uint
)
{
reserve
(
s
,
uint
::
next_power_of_two
(
n
+
1u
)
-
1u
)
}
...
...
@@ -1943,7 +1834,7 @@ fn reserve_at_least(s: &const ~str, n: uint) {
* Returns the number of single-byte characters the string can hold without
* reallocating
*/
pure
fn
capacity
(
s
:
&
const
~
str
)
->
uint
{
pu
b
pu
re
fn
capacity
(
s
:
&
const
~
str
)
->
uint
{
do
as_bytes
(
s
)
|
buf
|
{
let
vcap
=
vec
::
capacity
(
buf
);
assert
vcap
>
0u
;
...
...
@@ -1952,7 +1843,7 @@ fn reserve_at_least(s: &const ~str, n: uint) {
}
/// Escape each char in `s` with char::escape_default.
pure
fn
escape_default
(
s
:
&
str
)
->
~
str
{
pu
b
pu
re
fn
escape_default
(
s
:
&
str
)
->
~
str
{
let
mut
out
:
~
str
=
~
""
;
unsafe
{
reserve_at_least
(
&
mut
out
,
str
::
len
(
s
));
...
...
@@ -1964,7 +1855,7 @@ fn reserve_at_least(s: &const ~str, n: uint) {
}
/// Escape each char in `s` with char::escape_unicode.
pure
fn
escape_unicode
(
s
:
&
str
)
->
~
str
{
pu
b
pu
re
fn
escape_unicode
(
s
:
&
str
)
->
~
str
{
let
mut
out
:
~
str
=
~
""
;
unsafe
{
reserve_at_least
(
&
mut
out
,
str
::
len
(
s
));
...
...
@@ -1976,24 +1867,10 @@ fn reserve_at_least(s: &const ~str, n: uint) {
}
/// Unsafe operations
mod
raw
{
#[legacy_exports]
;
export
from_buf
,
from_buf_len
,
from_c_str
,
from_c_str_len
,
from_bytes
,
buf_as_slice
,
slice_bytes
,
view_bytes
,
push_byte
,
pop_byte
,
shift_byte
,
set_len
;
pub
mod
raw
{
/// Create a Rust string from a null-terminated *u8 buffer
unsafe
fn
from_buf
(
buf
:
*
u8
)
->
~
str
{
pub
unsafe
fn
from_buf
(
buf
:
*
u8
)
->
~
str
{
let
mut
curr
=
buf
,
i
=
0u
;
while
*
curr
!=
0u8
{
i
+=
1u
;
...
...
@@ -2003,7 +1880,7 @@ unsafe fn from_buf(buf: *u8) -> ~str {
}
/// Create a Rust string from a *u8 buffer of the given length
unsafe
fn
from_buf_len
(
buf
:
*
const
u8
,
len
:
uint
)
->
~
str
{
pub
unsafe
fn
from_buf_len
(
buf
:
*
const
u8
,
len
:
uint
)
->
~
str
{
let
mut
v
:
~
[
u8
]
=
vec
::
with_capacity
(
len
+
1
);
vec
::
as_mut_buf
(
v
,
|
vbuf
,
_
len
|
{
ptr
::
memcpy
(
vbuf
,
buf
as
*
u8
,
len
)
...
...
@@ -2016,27 +1893,27 @@ unsafe fn from_buf_len(buf: *const u8, len: uint) -> ~str {
}
/// Create a Rust string from a null-terminated C string
unsafe
fn
from_c_str
(
c_str
:
*
libc
::
c_char
)
->
~
str
{
pub
unsafe
fn
from_c_str
(
c_str
:
*
libc
::
c_char
)
->
~
str
{
from_buf
(::
cast
::
reinterpret_cast
(
&
c_str
))
}
/// Create a Rust string from a `*c_char` buffer of the given length
unsafe
fn
from_c_str_len
(
c_str
:
*
libc
::
c_char
,
len
:
uint
)
->
~
str
{
pub
unsafe
fn
from_c_str_len
(
c_str
:
*
libc
::
c_char
,
len
:
uint
)
->
~
str
{
from_buf_len
(::
cast
::
reinterpret_cast
(
&
c_str
),
len
)
}
/// Converts a vector of bytes to a string.
unsafe
fn
from_bytes
(
v
:
&
[
const
u8
])
->
~
str
{
pub
pub
unsafe
fn
from_bytes
(
v
:
&
[
const
u8
])
->
~
str
{
do
vec
::
as_const_buf
(
v
)
|
buf
,
len
|
{
from_buf_len
(
buf
,
len
)
}
}
/// Converts a byte to a string.
unsafe
fn
from_byte
(
u
:
u8
)
->
~
str
{
raw
::
from_bytes
([
u
])
}
pub
unsafe
fn
from_byte
(
u
:
u8
)
->
~
str
{
raw
::
from_bytes
([
u
])
}
/// Form a slice from a *u8 buffer of the given length without copying.
unsafe
fn
buf_as_slice
<
T
>
(
buf
:
*
u8
,
len
:
uint
,
pub
unsafe
fn
buf_as_slice
<
T
>
(
buf
:
*
u8
,
len
:
uint
,
f
:
fn
(
v
:
&
str
)
->
T
)
->
T
{
let
v
=
(
buf
,
len
+
1
);
assert
is_utf8
(::
cast
::
reinterpret_cast
(
&
v
));
...
...
@@ -2053,7 +1930,7 @@ unsafe fn buf_as_slice<T>(buf: *u8, len: uint,
* If begin is greater than end.
* If end is greater than the length of the string.
*/
unsafe
fn
slice_bytes
(
s
:
&
str
,
begin
:
uint
,
end
:
uint
)
->
~
str
{
pub
unsafe
fn
slice_bytes
(
s
:
&
str
,
begin
:
uint
,
end
:
uint
)
->
~
str
{
do
as_buf
(
s
)
|
sbuf
,
n
|
{
assert
(
begin
<=
end
);
assert
(
end
<=
n
);
...
...
@@ -2083,7 +1960,7 @@ unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> ~str {
* If end is greater than the length of the string.
*/
#[inline]
unsafe
fn
view_bytes
(
s
:
&
str
,
begin
:
uint
,
end
:
uint
)
->
&
str
{
pub
unsafe
fn
view_bytes
(
s
:
&
str
,
begin
:
uint
,
end
:
uint
)
->
&
str
{
do
as_buf
(
s
)
|
sbuf
,
n
|
{
assert
(
begin
<=
end
);
assert
(
end
<=
n
);
...
...
@@ -2094,7 +1971,7 @@ unsafe fn view_bytes(s: &str, begin: uint, end: uint) -> &str {
}
/// Appends a byte to a string. (Not UTF-8 safe).
unsafe
fn
push_byte
(
s
:
&
const
~
str
,
b
:
u8
)
{
pub
unsafe
fn
push_byte
(
s
:
&
const
~
str
,
b
:
u8
)
{
reserve_at_least
(
s
,
s
.len
()
+
1
);
do
as_buf
(
*
s
)
|
buf
,
len
|
{
let
buf
:
*
mut
u8
=
::
cast
::
reinterpret_cast
(
&
buf
);
...
...
@@ -2110,7 +1987,7 @@ unsafe fn push_bytes(s: &const ~str, bytes: &[u8]) {
}
/// Removes the last byte from a string and returns it. (Not UTF-8 safe).
unsafe
fn
pop_byte
(
s
:
&
const
~
str
)
->
u8
{
pub
unsafe
fn
pop_byte
(
s
:
&
const
~
str
)
->
u8
{
let
len
=
len
(
*
s
);
assert
(
len
>
0u
);
let
b
=
s
[
len
-
1u
];
...
...
@@ -2119,7 +1996,7 @@ unsafe fn pop_byte(s: &const ~str) -> u8 {
}
/// Removes the first byte from a string and returns it. (Not UTF-8 safe).
unsafe
fn
shift_byte
(
s
:
&
mut
~
str
)
->
u8
{
pub
unsafe
fn
shift_byte
(
s
:
&
mut
~
str
)
->
u8
{
let
len
=
len
(
*
s
);
assert
(
len
>
0u
);
let
b
=
s
[
0
];
...
...
@@ -2128,7 +2005,7 @@ unsafe fn shift_byte(s: &mut ~str) -> u8 {
}
/// Sets the length of the string and adds the null terminator
unsafe
fn
set_len
(
v
:
&
const
~
str
,
new_len
:
uint
)
{
pub
unsafe
fn
set_len
(
v
:
&
const
~
str
,
new_len
:
uint
)
{
let
v
:
**
vec
::
raw
::
VecRepr
=
cast
::
transmute
(
copy
v
);
let
repr
:
*
vec
::
raw
::
VecRepr
=
*
v
;
(
*
repr
)
.unboxed.fill
=
new_len
+
1u
;
...
...
@@ -2149,7 +2026,7 @@ fn test_from_buf_len() {
}
trait
UniqueStr
{
pub
trait
UniqueStr
{
fn
trim
()
->
self
;
fn
trim_left
()
->
self
;
fn
trim_right
()
->
self
;
...
...
@@ -2169,8 +2046,7 @@ fn trim_right() -> ~str { trim_right(self) }
}
#[cfg(notest)]
mod
traits
{
#[legacy_exports]
;
pub
mod
traits
{
impl
~
str
:
Add
<&
str
,
~
str
>
{
#[inline(always)]
pure
fn
add
(
rhs
:
&
&
str
)
->
~
str
{
...
...
@@ -2180,10 +2056,9 @@ impl ~str : Add<&str,~str> {
}
#[cfg(test)]
mod
traits
{
#[legacy_exports]
;}
pub
mod
traits
{}
trait
StrSlice
{
pub
trait
StrSlice
{
fn
all
(
it
:
fn
(
char
)
->
bool
)
->
bool
;
fn
any
(
it
:
fn
(
char
)
->
bool
)
->
bool
;
fn
contains
(
needle
:
&
a
/
str
)
->
bool
;
...
...
@@ -2326,7 +2201,6 @@ fn escape_unicode() -> ~str { escape_unicode(self) }
#[cfg(test)]
mod
tests
{
#[legacy_exports]
;
use
libc
::
c_char
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录