/// A type used for the search index.
#[derive(Debug)]
pub(crate) struct RenderType {
- name: Option<String>,
- generics: Option<Vec<TypeWithKind>>,
+ id: Option<RenderTypeId>,
+ generics: Option<Vec<RenderType>>,
}
-/// Full type of functions/methods in the search index.
-#[derive(Debug)]
-pub(crate) struct IndexItemFunctionType {
- inputs: Vec<TypeWithKind>,
- output: Vec<TypeWithKind>,
-}
-
-impl Serialize for IndexItemFunctionType {
+impl Serialize for RenderType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
- // If we couldn't figure out a type, just write `null`.
- let has_missing = self.inputs.iter().chain(self.output.iter()).any(|i| i.ty.name.is_none());
- if has_missing {
- serializer.serialize_none()
- } else {
+ let id = match &self.id {
+ // 0 is a sentinel, everything else is one-indexed
+ None => 0,
+ Some(RenderTypeId::Index(idx)) => idx + 1,
+ _ => panic!("must convert render types to indexes before serializing"),
+ };
+ if let Some(generics) = &self.generics {
let mut seq = serializer.serialize_seq(None)?;
- seq.serialize_element(&self.inputs)?;
- match self.output.as_slice() {
- [] => {}
- [one] => seq.serialize_element(one)?,
- all => seq.serialize_element(all)?,
- }
+ seq.serialize_element(&id)?;
+ seq.serialize_element(generics)?;
seq.end()
+ } else {
+ id.serialize(serializer)
}
}
}
-#[derive(Debug)]
-pub(crate) struct TypeWithKind {
- ty: RenderType,
- kind: ItemType,
+#[derive(Clone, Debug)]
+pub(crate) enum RenderTypeId {
+ DefId(DefId),
+ Primitive(clean::PrimitiveType),
+ Index(usize),
}
-impl From<(RenderType, ItemType)> for TypeWithKind {
- fn from(x: (RenderType, ItemType)) -> TypeWithKind {
- TypeWithKind { ty: x.0, kind: x.1 }
- }
+/// Full type of functions/methods in the search index.
+#[derive(Debug)]
+pub(crate) struct IndexItemFunctionType {
+ inputs: Vec<RenderType>,
+ output: Vec<RenderType>,
}
-impl Serialize for TypeWithKind {
+impl Serialize for IndexItemFunctionType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
- let mut seq = serializer.serialize_seq(None)?;
- seq.serialize_element(&self.ty.name)?;
- seq.serialize_element(&self.kind)?;
- if let Some(generics) = &self.ty.generics {
- seq.serialize_element(generics)?;
+ // If we couldn't figure out a type, just write `0`.
+ let has_missing = self
+ .inputs
+ .iter()
+ .chain(self.output.iter())
+ .any(|i| i.id.is_none() && i.generics.is_none());
+ if has_missing {
+ 0.serialize(serializer)
+ } else {
+ let mut seq = serializer.serialize_seq(None)?;
+ match &self.inputs[..] {
+ [one] if one.generics.is_none() => seq.serialize_element(one)?,
+ _ => seq.serialize_element(&self.inputs)?,
+ }
+ match &self.output[..] {
+ [] => {}
+ [one] if one.generics.is_none() => seq.serialize_element(one)?,
+ _ => seq.serialize_element(&self.output)?,
+ }
+ seq.end()
}
- seq.end()
}
}
&[],
ImplRenderingParameters {
show_def_docs: true,
- is_on_foreign_type: false,
show_default_items: true,
show_non_assoc_items: true,
toggle_open_by_default,
ty = ty.print(cx),
);
if let Some(default) = default {
+ write!(w, " = ");
+
// FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the
// hood which adds noisy underscores and a type suffix to number literals.
// This hurts readability in this context especially when more complex expressions
// are involved and it doesn't add much of value.
// Find a way to print constants here without all that jazz.
- write!(w, " = {}", default.value(cx.tcx()).unwrap_or_else(|| default.expr(cx.tcx())));
+ write!(w, "{}", Escape(&default.value(cx.tcx()).unwrap_or_else(|| default.expr(cx.tcx()))));
}
}
&[],
ImplRenderingParameters {
show_def_docs: true,
- is_on_foreign_type: false,
show_default_items: true,
show_non_assoc_items: true,
toggle_open_by_default: true,
#[derive(Clone, Copy, Debug)]
struct ImplRenderingParameters {
show_def_docs: bool,
- is_on_foreign_type: bool,
show_default_items: bool,
/// Whether or not to show methods.
show_non_assoc_items: bool,
parent,
rendering_params.show_def_docs,
use_absolute,
- rendering_params.is_on_foreign_type,
aliases,
);
if toggled {
containing_item: &clean::Item,
show_def_docs: bool,
use_absolute: Option<bool>,
- is_on_foreign_type: bool,
// This argument is used to reference same type with different paths to avoid duplication
// in documentation pages for trait with automatic implementations like "Send" and "Sync".
aliases: &[String],
) {
- let id = cx.derive_id(match i.inner_impl().trait_ {
- Some(ref t) => {
- if is_on_foreign_type {
- get_id_for_impl_on_foreign_type(&i.inner_impl().for_, t, cx)
- } else {
- format!("impl-{}", small_url_encode(format!("{:#}", t.print(cx))))
- }
- }
- None => "impl".to_string(),
- });
+ let id =
+ cx.derive_id(get_id_for_impl(&i.inner_impl().for_, i.inner_impl().trait_.as_ref(), cx));
let aliases = if aliases.is_empty() {
String::new()
} else {
let mut ret = impls
.iter()
.filter_map(|it| {
- if let Some(ref i) = it.inner_impl().trait_ {
- let i_display = format!("{:#}", i.print(cx));
- let out = Escape(&i_display);
- let encoded =
- id_map.derive(small_url_encode(format!("impl-{:#}", i.print(cx))));
- let prefix = match it.inner_impl().polarity {
- ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
- ty::ImplPolarity::Negative => "!",
- };
- let generated =
- format!("<a href=\"#{}\">{}{}</a>", encoded, prefix, out);
- if links.insert(generated.clone()) { Some(generated) } else { None }
- } else {
- None
- }
+ let trait_ = it.inner_impl().trait_.as_ref()?;
+ let encoded =
+ id_map.derive(get_id_for_impl(&it.inner_impl().for_, Some(trait_), cx));
+
+ let i_display = format!("{:#}", trait_.print(cx));
+ let out = Escape(&i_display);
+ let prefix = match it.inner_impl().polarity {
+ ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
+ ty::ImplPolarity::Negative => "!",
+ };
+ let generated = format!("<a href=\"#{}\">{}{}</a>", encoded, prefix, out);
+ if links.insert(generated.clone()) { Some(generated) } else { None }
})
.collect::<Vec<String>>();
ret.sort();
}
}
-fn get_id_for_impl_on_foreign_type(
- for_: &clean::Type,
- trait_: &clean::Path,
- cx: &Context<'_>,
-) -> String {
- small_url_encode(format!("impl-{:#}-for-{:#}", trait_.print(cx), for_.print(cx)))
+fn get_id_for_impl(for_: &clean::Type, trait_: Option<&clean::Path>, cx: &Context<'_>) -> String {
+ match trait_ {
+ Some(t) => small_url_encode(format!("impl-{:#}-for-{:#}", t.print(cx), for_.print(cx))),
+ None => small_url_encode(format!("impl-{:#}", for_.print(cx))),
+ }
}
fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String, String)> {
i.trait_.as_ref().map(|trait_| {
// Alternative format produces no URLs,
// so this parameter does nothing.
- (
- format!("{:#}", i.for_.print(cx)),
- get_id_for_impl_on_foreign_type(&i.for_, trait_, cx),
- )
+ (format!("{:#}", i.for_.print(cx)), get_id_for_impl(&i.for_, Some(trait_), cx))
})
}
_ => None,
ItemType::ProcAttribute => ItemSection::AttributeMacros,
ItemType::ProcDerive => ItemSection::DeriveMacros,
ItemType::TraitAlias => ItemSection::TraitAliases,
- ItemType::Generic => unreachable!(),
}
}