Skip to content

Commit 8873e6a

Browse files
Nemo157Joshua Nelson
authored andcommitted
Generate search links when item doesn't exist in new platform
1 parent 9797746 commit 8873e6a

File tree

2 files changed

+53
-53
lines changed

2 files changed

+53
-53
lines changed

src/web/crate_details.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub struct CrateDetails {
4242
github_issues: Option<i32>,
4343
pub(crate) metadata: MetaData,
4444
is_library: bool,
45-
doc_targets: Option<Json>,
45+
pub(crate) doc_targets: Vec<String>,
4646
license: Option<String>,
4747
documentation_url: Option<String>,
4848
}
@@ -185,6 +185,18 @@ impl CrateDetails {
185185
default_target: rows.get(0).get(25),
186186
};
187187

188+
let doc_targets = {
189+
let data: Json = rows.get(0).get(22);
190+
data.as_array()
191+
.map(|array| {
192+
array
193+
.iter()
194+
.filter_map(|item| item.as_string().map(|s| s.to_owned()))
195+
.collect()
196+
})
197+
.unwrap_or_else(Vec::new)
198+
};
199+
188200
let mut crate_details = CrateDetails {
189201
name: rows.get(0).get(2),
190202
version: rows.get(0).get(3),
@@ -211,7 +223,7 @@ impl CrateDetails {
211223
github_issues: rows.get(0).get(20),
212224
metadata,
213225
is_library: rows.get(0).get(21),
214-
doc_targets: rows.get(0).get(22),
226+
doc_targets,
215227
license: rows.get(0).get(23),
216228
documentation_url: rows.get(0).get(24),
217229
};

src/web/rustdoc.rs

Lines changed: 39 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
292292
let path_in_latest = if !is_latest_version {
293293
let mut latest_path = req_path.clone();
294294
latest_path[2] = &latest_version;
295-
path_for_version(&latest_path, &crate_details.target_name, &conn)
295+
path_for_version(&latest_path, &crate_details.doc_targets, &conn)
296296
} else {
297297
Default::default()
298298
};
@@ -302,7 +302,7 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
302302
let mut inner_path = req_path.clone();
303303
// Drop the `rustdoc/:crate/:version[/:platform]` prefix
304304
inner_path.drain(..3);
305-
if inner_path[0] != crate_details.target_name {
305+
if inner_path.len() > 1 && crate_details.doc_targets.iter().any(|s| s == inner_path[0]) {
306306
inner_path.remove(0);
307307
}
308308
inner_path.join("/")
@@ -331,7 +331,7 @@ pub fn rustdoc_html_server_handler(req: &mut Request) -> IronResult<Response> {
331331
/// `rustdoc/crate/version[/platform]/module/[kind.name.html|index.html]`
332332
///
333333
/// Returns a path that can be appended to `/crate/version/` to create a complete URL.
334-
fn path_for_version(req_path: &[&str], target_name: &str, conn: &Connection) -> String {
334+
fn path_for_version(req_path: &[&str], known_platforms: &[String], conn: &Connection) -> String {
335335
// Simple case: page exists in the latest version, so just change the version number
336336
if File::from_path(&conn, &req_path.join("/")).is_some() {
337337
// NOTE: this adds 'index.html' if it wasn't there before
@@ -351,12 +351,8 @@ fn path_for_version(req_path: &[&str], target_name: &str, conn: &Connection) ->
351351
.expect("paths should be of the form <kind>.<name>.html")
352352
};
353353
// check if req_path[3] is the platform choice or the name of the crate
354-
// rustdoc generates a ../settings.html page, so if req_path[3] is not
355-
// the target, that doesn't necessarily mean it's a platform.
356-
// we also can't check if it's in TARGETS, since some targets have been
357-
// removed (looking at you, i686-apple-darwin)
358354
let concat_path;
359-
let crate_root = if req_path[3] != target_name && req_path.len() >= 5 {
355+
let crate_root = if known_platforms.iter().any(|s| s == req_path[3]) && req_path.len() >= 5 {
360356
concat_path = format!("{}/{}", req_path[3], req_path[4]);
361357
&concat_path
362358
} else {
@@ -375,52 +371,39 @@ pub fn target_redirect_handler(req: &mut Request) -> IronResult<Response> {
375371

376372
let crate_details = cexpect!(CrateDetails::new(&conn, &name, &version));
377373

378-
// /crate/:name/:version/target-redirect/:target/*path
379-
let (target, path) = {
380-
let mut path = req.url.path();
381-
path.drain(..4);
382-
let target = path[0];
383-
if target == crate_details.metadata.default_target {
384-
path.remove(0);
374+
// [crate, :name, :version, target-redirect, :target, *path]
375+
// is transformed to
376+
// [rustdoc, :name, :version, :target?, *path]
377+
// path might be empty, but target is guaranteed to be there because of the route used
378+
let file_path = {
379+
let mut file_path = req.url.path();
380+
file_path[0] = "rustdoc";
381+
file_path.remove(3);
382+
if file_path[3] == crate_details.metadata.default_target {
383+
file_path.remove(3);
384+
} else if file_path[4] != crate_details.target_name {
385+
// For non-default targets we only redirect to paths within the current crate
386+
file_path.drain(4..);
387+
file_path.push(&crate_details.target_name);
388+
file_path.push("index.html");
385389
}
386-
(target, path.join("/"))
390+
if let Some(last) = file_path.last_mut() {
391+
if *last == "" {
392+
*last = "index.html";
393+
}
394+
}
395+
file_path
387396
};
388397

389-
let file_path = format!(
390-
"rustdoc/{name}/{version}/{path}",
398+
let path = path_for_version(&file_path, &crate_details.doc_targets, &conn);
399+
let url = format!(
400+
"{base}/{name}/{version}/{path}",
401+
base = base,
391402
name = name,
392403
version = version,
393404
path = path
394405
);
395406

396-
// if the current page is not present on the other platform, link to the index page for the crate instead
397-
let url = if File::from_path(&conn, &file_path).is_some() {
398-
format!(
399-
"{base}/{name}/{version}/{path}",
400-
base = base,
401-
name = name,
402-
version = version,
403-
path = path
404-
)
405-
} else if target == crate_details.metadata.default_target {
406-
format!(
407-
"{base}/{name}/{version}/{target_name}/index.html",
408-
base = base,
409-
name = name,
410-
version = version,
411-
target_name = crate_details.target_name
412-
)
413-
} else {
414-
format!(
415-
"{base}/{name}/{version}/{target}/{target_name}/index.html",
416-
base = base,
417-
name = name,
418-
version = version,
419-
target = target,
420-
target_name = crate_details.target_name
421-
)
422-
};
423-
424407
let url = ctry!(Url::parse(&url));
425408
let mut resp = Response::with((status::Found, Redirect(url)));
426409
resp.headers.set(Expires(HttpDate(time::now())));
@@ -661,6 +644,8 @@ mod test {
661644
// check it searches for removed pages
662645
let redirect =
663646
latest_version_redirect("/dummy/0.1.0/dummy/struct.will-be-deleted.html", &web)?;
647+
// This must be a double redirect to deal with crates that failed to build in the
648+
// latest version
664649
assert_eq!(redirect, "/dummy/0.2.0/dummy?search=will-be-deleted");
665650
assert_redirect(
666651
"/dummy/0.2.0/dummy?search=will-be-deleted",
@@ -1037,8 +1022,8 @@ mod test {
10371022
.add_target("x86_64-pc-windows-msvc")
10381023
.create()?;
10391024

1040-
// For top-level items we redirect to the target-specific doc root as the top-level
1041-
// items can't know which target they're for
1025+
// For top-level items on non-default platforms we redirect to the target-specific doc
1026+
// root as the top-level items can't know which target they're for
10421027
assert_platform_links(
10431028
web,
10441029
"/dummy/0.4.0/settings.html",
@@ -1047,7 +1032,7 @@ mod test {
10471032
"x86_64-pc-windows-msvc",
10481033
"/dummy/0.4.0/x86_64-pc-windows-msvc/dummy/index.html",
10491034
),
1050-
("x86_64-unknown-linux-gnu", "/dummy/0.4.0/dummy/index.html"),
1035+
("x86_64-unknown-linux-gnu", "/dummy/0.4.0/settings.html"),
10511036
],
10521037
)?;
10531038

@@ -1093,7 +1078,7 @@ mod test {
10931078
&[
10941079
(
10951080
"x86_64-pc-windows-msvc",
1096-
"/dummy/0.4.0/x86_64-pc-windows-msvc/dummy/index.html",
1081+
"/dummy/0.4.0/x86_64-pc-windows-msvc/dummy?search=DefaultOnly",
10971082
),
10981083
(
10991084
"x86_64-unknown-linux-gnu",
@@ -1140,7 +1125,10 @@ mod test {
11401125
"x86_64-pc-windows-msvc",
11411126
"/dummy/0.4.0/x86_64-pc-windows-msvc/dummy/struct.WindowsOnly.html",
11421127
),
1143-
("x86_64-unknown-linux-gnu", "/dummy/0.4.0/dummy/index.html"),
1128+
(
1129+
"x86_64-unknown-linux-gnu",
1130+
"/dummy/0.4.0/dummy/?search=WindowsOnly",
1131+
),
11441132
],
11451133
)?;
11461134

0 commit comments

Comments
 (0)