Skip to content

Commit 15989ec

Browse files
jesse99brson
authored andcommitted
Made most of the URL functions pure.
This closes #3782.
1 parent c5ab47e commit 15989ec

File tree

1 file changed

+40
-34
lines changed

1 file changed

+40
-34
lines changed

src/libstd/net_url.rs

+40-34
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@ type UserInfo = {
2727

2828
pub type Query = ~[(~str, ~str)];
2929

30-
pub fn Url(scheme: ~str, user: Option<UserInfo>, host: ~str,
30+
pub pure fn Url(scheme: ~str, user: Option<UserInfo>, host: ~str,
3131
port: Option<~str>, path: ~str, query: Query,
3232
fragment: Option<~str>) -> Url {
3333
Url { scheme: move scheme, user: move user, host: move host,
3434
port: move port, path: move path, query: move query,
3535
fragment: move fragment }
3636
}
3737

38-
fn UserInfo(user: ~str, pass: Option<~str>) -> UserInfo {
38+
pure fn UserInfo(user: ~str, pass: Option<~str>) -> UserInfo {
3939
{user: move user, pass: move pass}
4040
}
4141

@@ -84,8 +84,9 @@ fn encode_inner(s: &str, full_url: bool) -> ~str {
8484
*
8585
* This function is compliant with RFC 3986.
8686
*/
87-
pub fn encode(s: &str) -> ~str {
88-
encode_inner(s, true)
87+
pub pure fn encode(s: &str) -> ~str {
88+
// unsafe only because encode_inner does (string) IO
89+
unsafe {encode_inner(s, true)}
8990
}
9091

9192
/**
@@ -95,8 +96,9 @@ pub fn encode(s: &str) -> ~str {
9596
* This function is compliant with RFC 3986.
9697
*/
9798

98-
pub fn encode_component(s: &str) -> ~str {
99-
encode_inner(s, false)
99+
pub pure fn encode_component(s: &str) -> ~str {
100+
// unsafe only because encode_inner does (string) IO
101+
unsafe {encode_inner(s, false)}
100102
}
101103

102104
fn decode_inner(s: &str, full_url: bool) -> ~str {
@@ -142,15 +144,17 @@ fn decode_inner(s: &str, full_url: bool) -> ~str {
142144
*
143145
* This will only decode escape sequences generated by encode_uri.
144146
*/
145-
pub fn decode(s: &str) -> ~str {
146-
decode_inner(s, true)
147+
pub pure fn decode(s: &str) -> ~str {
148+
// unsafe only because decode_inner does (string) IO
149+
unsafe {decode_inner(s, true)}
147150
}
148151

149152
/**
150153
* Decode a string encoded with percent encoding.
151154
*/
152-
pub fn decode_component(s: &str) -> ~str {
153-
decode_inner(s, false)
155+
pub pure fn decode_component(s: &str) -> ~str {
156+
// unsafe only because decode_inner does (string) IO
157+
unsafe {decode_inner(s, false)}
154158
}
155159

156160
fn encode_plus(s: &str) -> ~str {
@@ -264,19 +268,21 @@ pub fn decode_form_urlencoded(s: ~[u8]) ->
264268
}
265269

266270

267-
fn split_char_first(s: &str, c: char) -> (~str, ~str) {
271+
pure fn split_char_first(s: &str, c: char) -> (~str, ~str) {
268272
let len = str::len(s);
269273
let mut index = len;
270274
let mut mat = 0;
271-
do io::with_str_reader(s) |rdr| {
272-
let mut ch : char;
273-
while !rdr.eof() {
274-
ch = rdr.read_byte() as char;
275-
if ch == c {
276-
// found a match, adjust markers
277-
index = rdr.tell()-1;
278-
mat = 1;
279-
break;
275+
unsafe {
276+
do io::with_str_reader(s) |rdr| {
277+
let mut ch : char;
278+
while !rdr.eof() {
279+
ch = rdr.read_byte() as char;
280+
if ch == c {
281+
// found a match, adjust markers
282+
index = rdr.tell()-1;
283+
mat = 1;
284+
break;
285+
}
280286
}
281287
}
282288
}
@@ -288,7 +294,7 @@ fn split_char_first(s: &str, c: char) -> (~str, ~str) {
288294
}
289295
}
290296

291-
fn userinfo_from_str(uinfo: &str) -> UserInfo {
297+
pure fn userinfo_from_str(uinfo: &str) -> UserInfo {
292298
let (user, p) = split_char_first(uinfo, ':');
293299
let pass = if str::len(p) == 0 {
294300
option::None
@@ -315,12 +321,12 @@ impl UserInfo : Eq {
315321
pure fn ne(other: &UserInfo) -> bool { !self.eq(other) }
316322
}
317323

318-
fn query_from_str(rawquery: &str) -> Query {
324+
pure fn query_from_str(rawquery: &str) -> Query {
319325
let mut query: Query = ~[];
320326
if str::len(rawquery) != 0 {
321327
for str::split_char(rawquery, '&').each |p| {
322328
let (k, v) = split_char_first(*p, '=');
323-
query.push((decode_component(k), decode_component(v)));
329+
unsafe {query.push((decode_component(k), decode_component(v)));}
324330
};
325331
}
326332
return query;
@@ -340,7 +346,7 @@ pub pure fn query_to_str(query: Query) -> ~str {
340346
}
341347
342348
// returns the scheme and the rest of the url, or a parsing error
343-
pub fn get_scheme(rawurl: &str) -> result::Result<(~str, ~str), @~str> {
349+
pub pure fn get_scheme(rawurl: &str) -> result::Result<(~str, ~str), @~str> {
344350
for str::each_chari(rawurl) |i,c| {
345351
match c {
346352
'A' .. 'Z' | 'a' .. 'z' => loop,
@@ -387,7 +393,7 @@ impl Input : Eq {
387393
}
388394

389395
// returns userinfo, host, port, and unparsed part, or an error
390-
fn get_authority(rawurl: &str) ->
396+
pure fn get_authority(rawurl: &str) ->
391397
result::Result<(Option<UserInfo>, ~str, Option<~str>, ~str), @~str> {
392398
if !str::starts_with(rawurl, ~"//") {
393399
// there is no authority.
@@ -517,7 +523,7 @@ fn get_authority(rawurl: &str) ->
517523

518524
let end = end; // make end immutable so it can be captured
519525

520-
let host_is_end_plus_one: &fn() -> bool = || {
526+
let host_is_end_plus_one: &pure fn() -> bool = || {
521527
end+1 == len
522528
&& !['?', '#', '/'].contains(&(rawurl[end] as char))
523529
};
@@ -556,7 +562,7 @@ fn get_authority(rawurl: &str) ->
556562

557563

558564
// returns the path and unparsed part of url, or an error
559-
fn get_path(rawurl: &str, authority : bool) ->
565+
pure fn get_path(rawurl: &str, authority : bool) ->
560566
result::Result<(~str, ~str), @~str> {
561567
let len = str::len(rawurl);
562568
let mut end = len;
@@ -587,7 +593,7 @@ fn get_path(rawurl: &str, authority : bool) ->
587593
}
588594

589595
// returns the parsed query and the fragment, if present
590-
fn get_query_fragment(rawurl: &str) ->
596+
pure fn get_query_fragment(rawurl: &str) ->
591597
result::Result<(Query, Option<~str>), @~str> {
592598
if !str::starts_with(rawurl, ~"?") {
593599
if str::starts_with(rawurl, ~"#") {
@@ -619,42 +625,42 @@ fn get_query_fragment(rawurl: &str) ->
619625
*
620626
*/
621627
622-
pub fn from_str(rawurl: &str) -> result::Result<Url, ~str> {
628+
pub pure fn from_str(rawurl: &str) -> result::Result<Url, ~str> {
623629
// scheme
624630
let mut schm = get_scheme(rawurl);
625631
if result::is_err(&schm) {
626632
return result::Err(copy *result::get_err(&schm));
627633
}
628-
let (scheme, rest) = result::unwrap(schm);
634+
let (scheme, rest) = schm.get();
629635
630636
// authority
631637
let mut auth = get_authority(rest);
632638
if result::is_err(&auth) {
633639
return result::Err(copy *result::get_err(&auth));
634640
}
635-
let (userinfo, host, port, rest) = result::unwrap(auth);
641+
let (userinfo, host, port, rest) = auth.get();
636642
637643
// path
638644
let has_authority = if host == ~"" { false } else { true };
639645
let mut pth = get_path(rest, has_authority);
640646
if result::is_err(&pth) {
641647
return result::Err(copy *result::get_err(&pth));
642648
}
643-
let (path, rest) = result::unwrap(pth);
649+
let (path, rest) = pth.get();
644650

645651
// query and fragment
646652
let mut qry = get_query_fragment(rest);
647653
if result::is_err(&qry) {
648654
return result::Err(copy *result::get_err(&qry));
649655
}
650-
let (query, fragment) = result::unwrap(qry);
656+
let (query, fragment) = qry.get();
651657

652658
return result::Ok(Url(scheme, userinfo, host,
653659
port, path, query, fragment));
654660
}
655661

656662
impl Url : FromStr {
657-
static fn from_str(s: &str) -> Option<Url> {
663+
static pure fn from_str(s: &str) -> Option<Url> {
658664
match from_str(s) {
659665
Ok(move url) => Some(url),
660666
Err(_) => None

0 commit comments

Comments
 (0)