Explorar el Código

Add URL serialization.

Simon Sapin hace 12 años
padre
commit
5635ac9073
Se han modificado 1 ficheros con 77 adiciones y 13 borrados
  1. 77 13
      url.rs

+ 77 - 13
url.rs

@@ -18,7 +18,7 @@ use encoding::all::UTF_8;
 use encoding::label::encoding_from_whatwg_label;
 use encoding::label::encoding_from_whatwg_label;
 
 
 
 
-pub struct ParsedURL {
+pub struct URL {
     scheme: ~str,
     scheme: ~str,
     scheme_data: SchemeData,
     scheme_data: SchemeData,
     query: Option<~str>,  // parse_form_urlencoded() parses this into ~[(~str, ~str)]
     query: Option<~str>,  // parse_form_urlencoded() parses this into ~[(~str, ~str)]
@@ -33,7 +33,7 @@ pub enum SchemeData {
 pub struct SchemeRelativeURL {
 pub struct SchemeRelativeURL {
     userinfo: Option<UserInfo>,
     userinfo: Option<UserInfo>,
     host: Host,
     host: Host,
-    port: Option<~str>,
+    port: ~str,
     path: ~[~str],
     path: ~[~str],
 }
 }
 
 
@@ -53,16 +53,80 @@ pub struct IPv6Address {
 }
 }
 
 
 
 
-pub fn parse_url(input: &str, base_url: Option<ParsedURL>)
-          -> Option<ParsedURL> {
-    let _ = input;
-    let _ = base_url;
-    None
-}
-
 pub type ParseResult<T> = Result<T, &'static str>;
 pub type ParseResult<T> = Result<T, &'static str>;
 
 
 
 
+impl URL {
+    pub fn parse(input: &str, base_url: Option<URL>) -> Option<URL> {
+        let _ = input;
+        let _ = base_url;
+        // TODO
+        None
+    }
+
+    pub fn serialize(&self) -> ~str {
+        let mut result = self.serialize_no_fragment();
+        match self.fragment {
+            None => (),
+            Some(ref fragment) => {
+                result.push_str("#");
+                result.push_str(fragment.as_slice());
+            }
+        }
+        result
+    }
+
+    pub fn serialize_no_fragment(&self) -> ~str {
+        let mut result = self.scheme.to_owned();
+        result.push_str(":");
+        match self.scheme_data {
+            RelativeSchemeData(SchemeRelativeURL {
+                userinfo: ref userinfo, host: ref host, port: ref port, path: ref path
+            }) => {
+                result.push_str("//");
+                match userinfo {
+                    &None => (),
+                    &Some(UserInfo { username: ref username, password: ref password })
+                    => if username.len() > 0 || password.is_some() {
+                        result.push_str(username.as_slice());
+                        match password {
+                            &None => (),
+                            &Some(ref password) => {
+                                result.push_str(":");
+                                result.push_str(password.as_slice());
+                            }
+                        }
+                        result.push_str("@");
+                    }
+                }
+                result.push_str(host.serialize());
+                if port.len() > 0 {
+                    result.push_str(":");
+                    result.push_str(port.as_slice());
+                }
+                if path.len() > 0 {
+                    for path_part in path.iter() {
+                        result.push_str("/");
+                        result.push_str(path_part.as_slice());
+                    }
+                } else {
+                    result.push_str("/");
+                }
+            },
+            OtherSchemeData(ref data) => result.push_str(data.as_slice()),
+        }
+        match self.query {
+            None => (),
+            Some(ref query) => {
+                result.push_str("?");
+                result.push_str(query.as_slice());
+            }
+        }
+        result
+    }
+}
+
+
 impl Host {
 impl Host {
     pub fn parse(input: &str) -> ParseResult<Host> {
     pub fn parse(input: &str) -> ParseResult<Host> {
         if input.len() == 0 {
         if input.len() == 0 {
@@ -462,13 +526,13 @@ mod tests {
                 query: expected_query,
                 query: expected_query,
                 fragment: expected_fragment
                 fragment: expected_fragment
             } = test;
             } = test;
-            let base = parse_url(base, None).unwrap();
-            let url = parse_url(input, Some(base));
+            let base = URL::parse(base, None).unwrap();
+            let url = URL::parse(input, Some(base));
             if expected_scheme.is_none() {
             if expected_scheme.is_none() {
                 assert!(url.is_none(), "Expected a parse error");
                 assert!(url.is_none(), "Expected a parse error");
                 continue
                 continue
             }
             }
-            let ParsedURL {
+            let URL {
                 scheme: scheme,
                 scheme: scheme,
                 scheme_data: scheme_data,
                 scheme_data: scheme_data,
                 query: query,
                 query: query,
@@ -488,7 +552,7 @@ mod tests {
                     assert_eq!(username, expected_username);
                     assert_eq!(username, expected_username);
                     assert_eq!(password, expected_password);
                     assert_eq!(password, expected_password);
                     assert_eq!(Some(host.serialize()), expected_host)
                     assert_eq!(Some(host.serialize()), expected_host)
-                    assert_eq!(port, expected_port);
+                    assert_eq!(Some(port), expected_port);
                     assert_eq!(Some(path.connect("/")), expected_path);
                     assert_eq!(Some(path.connect("/")), expected_path);
                 },
                 },
                 OtherSchemeData(scheme_data) => {
                 OtherSchemeData(scheme_data) => {