diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 949790cfe26..d79553a8be8 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -118,7 +118,7 @@ pub fn collapsed_doc_value(&self) -> Option { self.attrs.collapsed_doc_value() } - pub fn links(&self) -> Vec<(String, String)> { + pub fn links(&self) -> Vec { self.attrs.links(&self.def_id.krate) } @@ -441,6 +441,13 @@ pub struct ItemLink { pub(crate) fragment: Option, } +pub struct RenderedLink { + /// The text the link was original written as + pub(crate) original_text: String, + /// The URL to put in the `href` + pub(crate) href: String, +} + impl Attributes { /// Extracts the content from an attribute `#[doc(cfg(content))]`. pub fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> { @@ -617,7 +624,7 @@ pub fn collapsed_doc_value(&self) -> Option { /// Gets links as a vector /// /// Cache must be populated before call - pub fn links(&self, krate: &CrateNum) -> Vec<(String, String)> { + pub fn links(&self, krate: &CrateNum) -> Vec { use crate::html::format::href; use crate::html::render::CURRENT_DEPTH; @@ -631,7 +638,7 @@ pub fn links(&self, krate: &CrateNum) -> Vec<(String, String)> { href.push_str("#"); href.push_str(fragment); } - Some((s.clone(), href)) + Some(RenderedLink { original_text: s.clone(), href }) } else { None } @@ -651,16 +658,16 @@ pub fn links(&self, krate: &CrateNum) -> Vec<(String, String)> { }; // This is a primitive so the url is done "by hand". let tail = fragment.find('#').unwrap_or_else(|| fragment.len()); - Some(( - s.clone(), - format!( + Some(RenderedLink { + original_text: s.clone(), + href: format!( "{}{}std/primitive.{}.html{}", url, if !url.ends_with('/') { "/" } else { "" }, &fragment[..tail], &fragment[tail..] ), - )) + }) } else { panic!("This isn't a primitive?!"); } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index d54b8ea7478..e6484cd1c2c 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -34,6 +34,7 @@ use std::ops::Range; use std::str; +use crate::clean::RenderedLink; use crate::doctest; use crate::html::highlight; use crate::html::toc::TocBuilder; @@ -52,7 +53,7 @@ fn opts() -> Options { pub struct Markdown<'a>( pub &'a str, /// A list of link replacements. - pub &'a [(String, String)], + pub &'a [RenderedLink], /// The current list of used header IDs. pub &'a mut IdMap, /// Whether to allow the use of explicit error codes in doctest lang strings. @@ -78,7 +79,7 @@ pub struct MarkdownHtml<'a>( pub &'a Option, ); /// A tuple struct like `Markdown` that renders only the first paragraph. -pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [(String, String)]); +pub struct MarkdownSummaryLine<'a>(pub &'a str, pub &'a [RenderedLink]); #[derive(Copy, Clone, PartialEq, Debug)] pub enum ErrorCodes { @@ -339,11 +340,11 @@ fn dont_escape(c: u8) -> bool { /// Make headings links with anchor IDs and build up TOC. struct LinkReplacer<'a, 'b, I: Iterator>> { inner: I, - links: &'b [(String, String)], + links: &'b [RenderedLink], } impl<'a, 'b, I: Iterator>> LinkReplacer<'a, 'b, I> { - fn new(iter: I, links: &'b [(String, String)]) -> Self { + fn new(iter: I, links: &'b [RenderedLink]) -> Self { LinkReplacer { inner: iter, links } } } @@ -354,8 +355,8 @@ impl<'a, 'b, I: Iterator>> Iterator for LinkReplacer<'a, 'b, I> fn next(&mut self) -> Option { let event = self.inner.next(); if let Some(Event::Start(Tag::Link(kind, dest, text))) = event { - if let Some(&(_, ref replace)) = self.links.iter().find(|link| link.0 == *dest) { - Some(Event::Start(Tag::Link(kind, replace.to_owned().into(), text))) + if let Some(link) = self.links.iter().find(|link| link.original_text == *dest) { + Some(Event::Start(Tag::Link(kind, link.href.clone().into(), text))) } else { Some(Event::Start(Tag::Link(kind, dest, text))) } @@ -855,8 +856,8 @@ pub fn into_string(self) -> String { return String::new(); } let replacer = |_: &str, s: &str| { - if let Some(&(_, ref replace)) = links.iter().find(|link| &*link.0 == s) { - Some((replace.clone(), s.to_owned())) + if let Some(link) = links.iter().find(|link| &*link.original_text == s) { + Some((link.original_text.clone(), link.href.clone())) } else { None } @@ -933,8 +934,8 @@ pub fn into_string(self) -> String { } let replacer = |_: &str, s: &str| { - if let Some(&(_, ref replace)) = links.iter().find(|link| &*link.0 == s) { - Some((replace.clone(), s.to_owned())) + if let Some(rendered_link) = links.iter().find(|link| &*link.original_text == s) { + Some((rendered_link.original_text.clone(), rendered_link.href.clone())) } else { None } diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index e4aba8963c7..9dc85881482 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -63,7 +63,7 @@ use serde::ser::SerializeSeq; use serde::{Serialize, Serializer}; -use crate::clean::{self, AttributesExt, Deprecation, GetDefId, SelfTy, TypeKind}; +use crate::clean::{self, AttributesExt, Deprecation, GetDefId, RenderedLink, SelfTy, TypeKind}; use crate::config::RenderInfo; use crate::config::RenderOptions; use crate::docfs::{DocFS, PathError}; @@ -1780,7 +1780,7 @@ fn render_markdown( w: &mut Buffer, cx: &Context, md_text: &str, - links: Vec<(String, String)>, + links: Vec, prefix: &str, is_hidden: bool, ) {