diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index a21cf5266fe1f..56fee2c9fec2d 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -4,7 +4,7 @@ use std::path::Path; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::{sym, Symbol}; -use serde::Serialize; +use serde::ser::{Serialize, SerializeStruct, Serializer}; use crate::clean::types::{ FnDecl, FnRetTy, GenericBound, Generics, GetDefId, Type, TypeKind, WherePredicate, @@ -133,21 +133,69 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt< .map(|module| module.doc_value().map_or_else(String::new, |s| short_markdown_summary(&s))) .unwrap_or_default(); - #[derive(Serialize)] struct CrateData<'a> { doc: String, - #[serde(rename = "i")] items: Vec<&'a IndexItem>, - #[serde(rename = "p")] paths: Vec<(ItemType, String)>, // The String is alias name and the vec is the list of the elements with this alias. // // To be noted: the `usize` elements are indexes to `items`. - #[serde(rename = "a")] - #[serde(skip_serializing_if = "BTreeMap::is_empty")] aliases: &'a BTreeMap>, } + impl<'a> Serialize for CrateData<'a> { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let has_aliases = !self.aliases.is_empty(); + let mut crate_data = + serializer.serialize_struct("CrateData", if has_aliases { 9 } else { 8 })?; + crate_data.serialize_field("doc", &self.doc)?; + crate_data.serialize_field( + "t", + &self.items.iter().map(|item| &item.ty).collect::>(), + )?; + crate_data.serialize_field( + "n", + &self.items.iter().map(|item| &item.name).collect::>(), + )?; + crate_data.serialize_field( + "q", + &self.items.iter().map(|item| &item.path).collect::>(), + )?; + crate_data.serialize_field( + "d", + &self.items.iter().map(|item| &item.desc).collect::>(), + )?; + crate_data.serialize_field( + "i", + &self + .items + .iter() + .map(|item| { + assert_eq!( + item.parent.is_some(), + item.parent_idx.is_some(), + "`{}` is missing idx", + item.name + ); + item.parent_idx.map(|x| x + 1).unwrap_or(0) + }) + .collect::>(), + )?; + crate_data.serialize_field( + "f", + &self.items.iter().map(|item| &item.search_type).collect::>(), + )?; + crate_data.serialize_field("p", &self.paths)?; + if has_aliases { + crate_data.serialize_field("a", &self.aliases)?; + } + crate_data.end() + } + } + // Collect the index into a string format!( r#""{}":{}"#, diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index a4621fb8ed555..66c47f14655ba 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -166,23 +166,6 @@ crate struct IndexItem { crate search_type: Option, } -impl Serialize for IndexItem { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - assert_eq!( - self.parent.is_some(), - self.parent_idx.is_some(), - "`{}` is missing idx", - self.name - ); - - (self.ty, &self.name, &self.path, &self.desc, self.parent_idx, &self.search_type) - .serialize(serializer) - } -} - /// A type used for the search index. #[derive(Debug)] crate struct RenderType { diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 42519d596225b..ac2da5f779bd1 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -1847,13 +1847,18 @@ function defocusSearchBar() { }); currentIndex += 1; - // an array of [(Number) item type, - // (String) name, - // (String) full path or empty string for previous path, - // (String) description, - // (Number | null) the parent path index to `paths`] - // (Object | null) the type of the function (if any) - var items = rawSearchIndex[crate].i; + // an array of (Number) item types + var itemTypes = rawSearchIndex[crate].t; + // an array of (String) item names + var itemNames = rawSearchIndex[crate].n; + // an array of (String) full paths (or empty string for previous path) + var itemPaths = rawSearchIndex[crate].q; + // an array of (String) descriptions + var itemDescs = rawSearchIndex[crate].d; + // an array of (Number) the parent path index + 1 to `paths`, or 0 if none + var itemParentIdxs = rawSearchIndex[crate].i; + // an array of (Object | null) the type of the function, if any + var itemFunctionSearchTypes = rawSearchIndex[crate].f; // an array of [(Number) item type, // (String) name] var paths = rawSearchIndex[crate].p; @@ -1867,28 +1872,24 @@ function defocusSearchBar() { paths[i] = {ty: paths[i][0], name: paths[i][1]}; } - // convert `items` into an object form, and construct word indices. + // convert `item*` into an object form, and construct word indices. // // before any analysis is performed lets gather the search terms to // search against apart from the rest of the data. This is a quick // operation that is cached for the life of the page state so that // all other search operations have access to this cached data for // faster analysis operations - len = items.length; + len = itemTypes.length; var lastPath = ""; for (i = 0; i < len; ++i) { - var rawRow = items[i]; - if (!rawRow[2]) { - rawRow[2] = lastPath; - } var row = { crate: crate, - ty: rawRow[0], - name: rawRow[1], - path: rawRow[2], - desc: rawRow[3], - parent: paths[rawRow[4]], - type: rawRow[5], + ty: itemTypes[i], + name: itemNames[i], + path: itemPaths[i] ? itemPaths[i] : lastPath, + desc: itemDescs[i], + parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, + type: itemFunctionSearchTypes[i], }; searchIndex.push(row); if (typeof row.name === "string") {