Skip to content

Commit

Permalink
Auto merge of #133 - untitaker:issue-132-port-eq, r=SimonSapin
Browse files Browse the repository at this point in the history
Make port: None equal to port: default_port

Fix #132

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/rust-url/133)
<!-- Reviewable:end -->
  • Loading branch information
bors-servo committed Nov 10, 2015
2 parents a3cd772 + ab7f6fc commit fedf144
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 1 deletion.
43 changes: 42 additions & 1 deletion src/lib.rs
Expand Up @@ -137,6 +137,8 @@ use std::fmt::{self, Formatter};
use std::str;
use std::path::{Path, PathBuf};
use std::borrow::Borrow;
use std::hash::{Hash, Hasher};
use std::cmp::Ordering;

#[cfg(feature="serde_serialization")]
use std::str::FromStr;
Expand Down Expand Up @@ -226,7 +228,7 @@ pub enum SchemeData {
}

/// Components for URLs in a *relative* scheme such as HTTP.
#[derive(PartialEq, Eq, Clone, Debug, Hash, PartialOrd, Ord)]
#[derive(Clone, Debug)]
#[cfg_attr(feature="heap_size", derive(HeapSizeOf))]
pub struct RelativeSchemeData {
/// The username of the URL, as a possibly empty, percent-encoded string.
Expand Down Expand Up @@ -266,6 +268,45 @@ pub struct RelativeSchemeData {
pub path: Vec<String>,
}

impl RelativeSchemeData {
fn get_identity_key(&self) -> (&String, &Option<String>, &Host, Option<u16>, Option<u16>, &Vec<String>) {
(
&self.username,
&self.password,
&self.host,
self.port.or(self.default_port),
self.default_port,
&self.path
)
}
}


impl PartialEq for RelativeSchemeData {
fn eq(&self, other: &RelativeSchemeData) -> bool {
self.get_identity_key() == other.get_identity_key()
}
}

impl Eq for RelativeSchemeData {}

impl Hash for RelativeSchemeData {
fn hash<H: Hasher>(&self, state: &mut H) {
self.get_identity_key().hash(state)
}
}

impl PartialOrd for RelativeSchemeData {
fn partial_cmp(&self, other: &RelativeSchemeData) -> Option<Ordering> {
self.get_identity_key().partial_cmp(&other.get_identity_key())
}
}

impl Ord for RelativeSchemeData {
fn cmp(&self, other: &Self) -> Ordering {
self.get_identity_key().cmp(&other.get_identity_key())
}
}

impl str::FromStr for Url {
type Err = ParseError;
Expand Down
46 changes: 46 additions & 0 deletions src/tests.rs
Expand Up @@ -301,3 +301,49 @@ fn issue_124() {
let url: Url = "file:..".parse().unwrap();
assert_eq!(url.path().unwrap(), [""]);
}

#[test]
fn relative_scheme_data_equality() {
use std::hash::{Hash, Hasher, SipHasher};

fn check_eq(a: &Url, b: &Url) {
assert_eq!(a, b);

let mut h1 = SipHasher::new();
a.hash(&mut h1);
let mut h2 = SipHasher::new();
b.hash(&mut h2);
assert_eq!(h1.finish(), h2.finish());
}

fn url(s: &str) -> Url {
let rv = s.parse().unwrap();
check_eq(&rv, &rv);
rv
}

// Doesn't care if default port is given.
let a: Url = url("https://example.com/");
let b: Url = url("https://example.com:443/");
check_eq(&a, &b);

// Different ports
let a: Url = url("http://example.com/");
let b: Url = url("http://example.com:8080/");
assert!(a != b);

// Different scheme
let a: Url = url("http://example.com/");
let b: Url = url("https://example.com/");
assert!(a != b);

// Different host
let a: Url = url("http://foo.com/");
let b: Url = url("http://bar.com/");
assert!(a != b);

// Missing path, automatically substituted. Semantically the same.
let a: Url = url("http://foo.com");
let b: Url = url("http://foo.com/");
check_eq(&a, &b);
}

0 comments on commit fedf144

Please sign in to comment.