diff --git a/src/web/crate_details.rs b/src/web/crate_details.rs index 769a7782d..1d91820e4 100644 --- a/src/web/crate_details.rs +++ b/src/web/crate_details.rs @@ -255,15 +255,13 @@ impl CrateDetails { Some(crate_details) } - /// Returns all versions of this crate. - pub fn versions(&self) -> Vec { - self.releases.iter() - .map(|release| release.version.clone()) - .collect() + /// Returns the version of the latest release of this crate. + pub fn latest_version(&self) -> &str { + // releases will always contain at least one element + &self.releases[0].version } } - fn map_to_release(conn: &Connection, crate_id: i32, version: String) -> Release { let rows = conn.query( "SELECT build_status @@ -393,27 +391,53 @@ mod tests { } #[test] - fn test_versions() { + fn test_releases_should_be_sorted() { crate::test::wrapper(|env| { let db = env.db(); // Add new releases of 'foo' out-of-order since CrateDetails should sort them descending - create_release(&db, "foo", "0.0.1", true)?; - create_release(&db, "foo", "0.0.3", false)?; + create_release(&db, "foo", "0.1.0", true)?; + create_release(&db, "foo", "0.1.1", true)?; + create_release(&db, "foo", "0.3.0", false)?; create_release(&db, "foo", "1.0.0", true)?; - create_release(&db, "foo", "0.0.2", true)?; + create_release(&db, "foo", "0.12.0", true)?; + create_release(&db, "foo", "0.2.0", true)?; + create_release(&db, "foo", "0.2.0-alpha", true)?; - let details = CrateDetails::new(&db.conn(), "foo", "0.0.2").unwrap(); - - assert_eq!(details.versions(), vec!["1.0.0", "0.0.3", "0.0.2", "0.0.1"]); + let details = CrateDetails::new(&db.conn(), "foo", "0.2.0").unwrap(); assert_eq!(details.releases, vec![ Release { version: "1.0.0".to_string(), build_status: true }, - Release { version: "0.0.3".to_string(), build_status: false }, - Release { version: "0.0.2".to_string(), build_status: true }, - Release { version: "0.0.1".to_string(), build_status: true }, + Release { version: "0.12.0".to_string(), build_status: true }, + Release { version: "0.3.0".to_string(), build_status: false }, + Release { version: "0.2.0".to_string(), build_status: true }, + Release { version: "0.2.0-alpha".to_string(), build_status: true }, + Release { version: "0.1.1".to_string(), build_status: true }, + Release { version: "0.1.0".to_string(), build_status: true }, ]); Ok(()) }); } + + #[test] + fn test_latest_version() { + crate::test::wrapper(|env| { + let db = env.db(); + + db.fake_release().name("foo").version("0.0.1").create()?; + db.fake_release().name("foo").version("0.0.3").create()?; + db.fake_release().name("foo").version("0.0.2").create()?; + + let details = CrateDetails::new(&db.conn(), "foo", "0.0.1").unwrap(); + assert_eq!(details.latest_version(), "0.0.3"); + + let details = CrateDetails::new(&db.conn(), "foo", "0.0.2").unwrap(); + assert_eq!(details.latest_version(), "0.0.3"); + + let details = CrateDetails::new(&db.conn(), "foo", "0.0.3").unwrap(); + assert_eq!(details.latest_version(), "0.0.3"); + + Ok(()) + }) + } } diff --git a/src/web/mod.rs b/src/web/mod.rs index f1cf5f3da..3fe82f2e6 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -313,39 +313,6 @@ fn render_markdown(text: &str) -> String { -/// Returns latest version if required version is not the latest -/// req_version must be an exact version -fn latest_version(versions_json: &Vec, req_version: &str) -> Option { - let req_version = match Version::parse(req_version) { - Ok(v) => v, - Err(_) => return None, - }; - let versions = { - let mut versions: Vec = Vec::new(); - for version in versions_json { - let version = match Version::parse(&version) { - Ok(v) => v, - Err(_) => return None, - }; - versions.push(version); - } - - versions.sort(); - versions.reverse(); - versions - }; - - if req_version != versions[0] { - for i in 1..versions.len() { - if req_version == versions[i] { - return Some(format!("{}", versions[0])) - } - } - } - None -} - - pub struct Server { inner: Listening, } @@ -537,7 +504,6 @@ impl ToJson for MetaData { #[cfg(test)] mod test { extern crate env_logger; - use super::*; #[test] fn test_index_returns_success() { @@ -547,16 +513,4 @@ mod test { Ok(()) }); } - - #[test] - fn test_latest_version() { - let versions = vec!["1.0.0".to_string(), - "1.1.0".to_string(), - "0.9.0".to_string(), - "0.9.1".to_string()]; - assert_eq!(latest_version(&versions, "1.1.0"), None); - assert_eq!(latest_version(&versions, "1.0.0"), Some("1.1.0".to_owned())); - assert_eq!(latest_version(&versions, "0.9.0"), Some("1.1.0".to_owned())); - assert_eq!(latest_version(&versions, "invalidversion"), None); - } } diff --git a/src/web/rustdoc.rs b/src/web/rustdoc.rs index 34c6be660..31d94ed44 100644 --- a/src/web/rustdoc.rs +++ b/src/web/rustdoc.rs @@ -3,7 +3,7 @@ use super::pool::Pool; use super::file::File; -use super::{latest_version, redirect_base}; +use super::redirect_base; use super::crate_details::CrateDetails; use iron::prelude::*; use iron::{status, Url}; @@ -262,9 +262,13 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult { content.full = file_content; let crate_details = cexpect!(CrateDetails::new(&conn, &name, &version)); - let (path, version) = if let Some(version) = latest_version(&crate_details.versions(), &version) { - req_path[2] = &version; - (path_for_version(&req_path, &crate_details.target_name, &conn), version) + + let latest_version = crate_details.latest_version().to_owned(); + let is_latest_version = latest_version == version; + + let path = if !is_latest_version { + req_path[2] = &latest_version; + path_for_version(&req_path, &crate_details.target_name, &conn) } else { Default::default() }; @@ -275,9 +279,9 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult { .set_true("show_package_navigation") .set_true("package_navigation_documentation_tab") .set_true("package_navigation_show_platforms_tab") - .set_bool("is_latest_version", path.is_empty()) + .set_bool("is_latest_version", is_latest_version) .set("path_in_latest", &path) - .set("latest_version", &version) + .set("latest_version", &latest_version) .to_resp("rustdoc") }