Merge all loops into one when generating search index

This commit is contained in:
Guillaume Gomez 2023-09-01 14:46:47 +02:00
parent 05eda41658
commit 36fa557a5e

View File

@ -265,102 +265,75 @@ pub(crate) fn build_index<'tcx>(
})
.collect::<Vec<_>>();
let mut names = Vec::with_capacity(self.items.len());
let mut types = String::with_capacity(self.items.len());
let mut full_paths = Vec::with_capacity(self.items.len());
let mut descriptions = Vec::with_capacity(self.items.len());
let mut parents = Vec::with_capacity(self.items.len());
let mut functions = Vec::with_capacity(self.items.len());
let mut deprecated = Vec::with_capacity(self.items.len());
for (index, item) in self.items.iter().enumerate() {
let n = item.ty as u8;
let c = char::try_from(n + b'A').expect("item types must fit in ASCII");
assert!(c <= 'z', "item types must fit within ASCII printables");
types.push(c);
assert_eq!(
item.parent.is_some(),
item.parent_idx.is_some(),
"`{}` is missing idx",
item.name
);
// 0 is a sentinel, everything else is one-indexed
parents.push(item.parent_idx.map(|x| x + 1).unwrap_or(0));
names.push(item.name.as_str());
descriptions.push(&item.desc);
if !item.path.is_empty() {
full_paths.push((index, &item.path));
}
// Fake option to get `0` out as a sentinel instead of `null`.
// We want to use `0` because it's three less bytes.
enum FunctionOption<'a> {
Function(&'a IndexItemFunctionType),
None,
}
impl<'a> Serialize for FunctionOption<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
FunctionOption::None => 0.serialize(serializer),
FunctionOption::Function(ty) => ty.serialize(serializer),
}
}
}
functions.push(match &item.search_type {
Some(ty) => FunctionOption::Function(ty),
None => FunctionOption::None,
});
if item.deprecation.is_some() {
deprecated.push(index);
}
}
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| {
let n = item.ty as u8;
let c = char::try_from(n + b'A').expect("item types must fit in ASCII");
assert!(c <= 'z', "item types must fit within ASCII printables");
c
})
.collect::<String>(),
)?;
crate_data.serialize_field(
"n",
&self.items.iter().map(|item| item.name.as_str()).collect::<Vec<_>>(),
)?;
crate_data.serialize_field(
"q",
&self
.items
.iter()
.enumerate()
// Serialize as an array of item indices and full paths
.filter_map(
|(index, item)| {
if item.path.is_empty() { None } else { Some((index, &item.path)) }
},
)
.collect::<Vec<_>>(),
)?;
crate_data.serialize_field(
"d",
&self.items.iter().map(|item| &item.desc).collect::<Vec<_>>(),
)?;
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
);
// 0 is a sentinel, everything else is one-indexed
item.parent_idx.map(|x| x + 1).unwrap_or(0)
})
.collect::<Vec<_>>(),
)?;
crate_data.serialize_field(
"f",
&self
.items
.iter()
.map(|item| {
// Fake option to get `0` out as a sentinel instead of `null`.
// We want to use `0` because it's three less bytes.
enum FunctionOption<'a> {
Function(&'a IndexItemFunctionType),
None,
}
impl<'a> Serialize for FunctionOption<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
FunctionOption::None => 0.serialize(serializer),
FunctionOption::Function(ty) => ty.serialize(serializer),
}
}
}
match &item.search_type {
Some(ty) => FunctionOption::Function(ty),
None => FunctionOption::None,
}
})
.collect::<Vec<_>>(),
)?;
crate_data.serialize_field(
"c",
&self
.items
.iter()
.enumerate()
// Serialize as an array of deprecated item indices
.filter_map(|(index, item)| item.deprecation.map(|_| index))
.collect::<Vec<_>>(),
)?;
crate_data.serialize_field("t", &types)?;
crate_data.serialize_field("n", &names)?;
// Serialize as an array of item indices and full paths
crate_data.serialize_field("q", &full_paths)?;
crate_data.serialize_field("d", &descriptions)?;
crate_data.serialize_field("i", &parents)?;
crate_data.serialize_field("f", &functions)?;
crate_data.serialize_field("c", &deprecated)?;
crate_data.serialize_field("p", &paths)?;
if has_aliases {
crate_data.serialize_field("a", &self.aliases)?;