replace serialize with serde in rustdoc

This commit is contained in:
Andy Russell 2019-06-29 13:30:45 -04:00
parent e9469a6aec
commit 94630d4c8b
No known key found for this signature in database
GPG Key ID: BE2221033EDBC374
6 changed files with 125 additions and 69 deletions

View File

@ -3924,6 +3924,8 @@ dependencies = [
"minifier", "minifier",
"pulldown-cmark 0.5.3", "pulldown-cmark 0.5.3",
"rustc-rayon", "rustc-rayon",
"serde",
"serde_json",
"tempfile", "tempfile",
] ]

View File

@ -12,4 +12,6 @@ path = "lib.rs"
pulldown-cmark = { version = "0.5.3", default-features = false } pulldown-cmark = { version = "0.5.3", default-features = false }
minifier = "0.0.33" minifier = "0.0.33"
rayon = { version = "0.3.0", package = "rustc-rayon" } rayon = { version = "0.3.0", package = "rustc-rayon" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
tempfile = "3" tempfile = "3"

View File

@ -1,7 +1,11 @@
//! Item types. //! Item types.
use std::fmt; use std::fmt;
use serde::{Serialize, Serializer};
use syntax_pos::hygiene::MacroKind; use syntax_pos::hygiene::MacroKind;
use crate::clean; use crate::clean;
/// Item type. Corresponds to `clean::ItemEnum` variants. /// Item type. Corresponds to `clean::ItemEnum` variants.
@ -45,6 +49,14 @@ pub enum ItemType {
TraitAlias = 25, TraitAlias = 25,
} }
impl Serialize for ItemType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
(*self as u8).serialize(serializer)
}
}
impl<'a> From<&'a clean::Item> for ItemType { impl<'a> From<&'a clean::Item> for ItemType {
fn from(item: &'a clean::Item) -> ItemType { fn from(item: &'a clean::Item) -> ItemType {

View File

@ -31,7 +31,8 @@ use std::cmp::Ordering;
use std::collections::{BTreeMap, VecDeque}; use std::collections::{BTreeMap, VecDeque};
use std::default::Default; use std::default::Default;
use std::error; use std::error;
use std::fmt::{self, Formatter, Write as FmtWrite};
use std::fmt::{self, Formatter, Write};
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fs::{self, File}; use std::fs::{self, File};
use std::io::prelude::*; use std::io::prelude::*;
@ -42,7 +43,8 @@ use std::sync::Arc;
use std::rc::Rc; use std::rc::Rc;
use errors; use errors;
use serialize::json::{ToJson, Json, as_json}; use serde::{Serialize, Serializer};
use serde::ser::SerializeSeq;
use syntax::ast; use syntax::ast;
use syntax::edition::Edition; use syntax::edition::Edition;
use syntax::print::pprust; use syntax::print::pprust;
@ -303,19 +305,22 @@ struct IndexItem {
search_type: Option<IndexItemFunctionType>, search_type: Option<IndexItemFunctionType>,
} }
impl ToJson for IndexItem { impl Serialize for IndexItem {
fn to_json(&self) -> Json { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
assert_eq!(self.parent.is_some(), self.parent_idx.is_some()); assert_eq!(self.parent.is_some(), self.parent_idx.is_some());
let mut data = Vec::with_capacity(6); (
data.push((self.ty as usize).to_json()); self.ty,
data.push(self.name.to_json()); &self.name,
data.push(self.path.to_json()); &self.path,
data.push(self.desc.to_json()); &self.desc,
data.push(self.parent_idx.to_json()); self.parent_idx,
data.push(self.search_type.to_json()); &self.search_type,
)
Json::Array(data) .serialize(serializer)
} }
} }
@ -326,18 +331,20 @@ struct Type {
generics: Option<Vec<String>>, generics: Option<Vec<String>>,
} }
impl ToJson for Type { impl Serialize for Type {
fn to_json(&self) -> Json { fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
match self.name { where
Some(ref name) => { S: Serializer,
let mut data = Vec::with_capacity(2); {
data.push(name.to_json()); if let Some(name) = &self.name {
if let Some(ref generics) = self.generics { let mut seq = serializer.serialize_seq(None)?;
data.push(generics.to_json()); seq.serialize_element(&name)?;
} if let Some(generics) = &self.generics {
Json::Array(data) seq.serialize_element(&generics)?;
} }
None => Json::Null, seq.end()
} else {
serializer.serialize_none()
} }
} }
} }
@ -349,26 +356,29 @@ struct IndexItemFunctionType {
output: Option<Vec<Type>>, output: Option<Vec<Type>>,
} }
impl ToJson for IndexItemFunctionType { impl Serialize for IndexItemFunctionType {
fn to_json(&self) -> Json { 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`. // If we couldn't figure out a type, just write `null`.
let mut iter = self.inputs.iter(); let mut iter = self.inputs.iter();
if match self.output { if match self.output {
Some(ref output) => iter.chain(output.iter()).any(|ref i| i.name.is_none()), Some(ref output) => iter.chain(output.iter()).any(|ref i| i.name.is_none()),
None => iter.any(|ref i| i.name.is_none()), None => iter.any(|ref i| i.name.is_none()),
} { } {
Json::Null serializer.serialize_none()
} else { } else {
let mut data = Vec::with_capacity(2); let mut seq = serializer.serialize_seq(None)?;
data.push(self.inputs.to_json()); seq.serialize_element(&self.inputs)?;
if let Some(ref output) = self.output { if let Some(output) = &self.output {
if output.len() > 1 { if output.len() > 1 {
data.push(output.to_json()); seq.serialize_element(&output)?;
} else { } else {
data.push(output[0].to_json()); seq.serialize_element(&output[0])?;
} }
} }
Json::Array(data) seq.end()
} }
} }
} }
@ -596,7 +606,7 @@ fn write_shared(
// To avoid theme switch latencies as much as possible, we put everything theme related // To avoid theme switch latencies as much as possible, we put everything theme related
// at the beginning of the html files into another js file. // at the beginning of the html files into another js file.
let theme_js = format!( let theme_js = format!(
r#"var themes = document.getElementById("theme-choices"); r#"var themes = document.getElementById("theme-choices");
var themePicker = document.getElementById("theme-picker"); var themePicker = document.getElementById("theme-picker");
function showThemeButtonState() {{ function showThemeButtonState() {{
@ -642,8 +652,8 @@ themePicker.onblur = handleThemeButtonsBlur;
}}; }};
but.onblur = handleThemeButtonsBlur; but.onblur = handleThemeButtonsBlur;
themes.appendChild(but); themes.appendChild(but);
}});"#, }});"#, serde_json::to_string(&themes).unwrap());
as_json(&themes));
write_minify(&cx.shared.fs, cx.path("theme.js"), write_minify(&cx.shared.fs, cx.path("theme.js"),
&theme_js, &theme_js,
options.enable_minification)?; options.enable_minification)?;
@ -932,32 +942,48 @@ themePicker.onblur = handleThemeButtonsBlur;
} }
}; };
let mut have_impls = false; #[derive(Serialize)]
let mut implementors = format!(r#"implementors["{}"] = ["#, krate.name); struct Implementor {
for imp in imps { text: String,
// If the trait and implementation are in the same crate, then synthetic: bool,
// there's no need to emit information about it (there's inlining types: Vec<String>,
// going on). If they're in different crates then the crate defining
// the trait will be interested in our implementation.
if imp.impl_item.def_id.krate == did.krate { continue }
// If the implementation is from another crate then that crate
// should add it.
if !imp.impl_item.def_id.is_local() { continue }
have_impls = true;
write!(implementors, "{{text:{},synthetic:{},types:{}}},",
as_json(&imp.inner_impl().print().to_string()),
imp.inner_impl().synthetic,
as_json(&collect_paths_for_type(imp.inner_impl().for_.clone()))).unwrap();
} }
implementors.push_str("];");
let implementors = imps
.iter()
.filter_map(|imp| {
// If the trait and implementation are in the same crate, then
// there's no need to emit information about it (there's inlining
// going on). If they're in different crates then the crate defining
// the trait will be interested in our implementation.
//
// If the implementation is from another crate then that crate
// should add it.
if imp.impl_item.def_id.krate == did.krate || !imp.impl_item.def_id.is_local() {
None
} else {
Some(Implementor {
text: imp.inner_impl().print().to_string(),
synthetic: imp.inner_impl().synthetic,
types: collect_paths_for_type(imp.inner_impl().for_.clone()),
})
}
})
.collect::<Vec<_>>();
// Only create a js file if we have impls to add to it. If the trait is // Only create a js file if we have impls to add to it. If the trait is
// documented locally though we always create the file to avoid dead // documented locally though we always create the file to avoid dead
// links. // links.
if !have_impls && !cx.cache.paths.contains_key(&did) { if implementors.is_empty() && !cx.cache.paths.contains_key(&did) {
continue; continue;
} }
let implementors = format!(
r#"implementors["{}"] = {};"#,
krate.name,
serde_json::to_string(&implementors).unwrap()
);
let mut mydst = dst.clone(); let mut mydst = dst.clone();
for part in &remote_path[..remote_path.len() - 1] { for part in &remote_path[..remote_path.len() - 1] {
mydst.push(part); mydst.push(part);
@ -1456,7 +1482,7 @@ impl Context {
if !self.render_redirect_pages { if !self.render_redirect_pages {
let items = self.build_sidebar_items(&m); let items = self.build_sidebar_items(&m);
let js_dst = self.dst.join("sidebar-items.js"); let js_dst = self.dst.join("sidebar-items.js");
let v = format!("initSidebarItems({});", as_json(&items)); let v = format!("initSidebarItems({});", serde_json::to_string(&items).unwrap());
scx.fs.write(&js_dst, &v)?; scx.fs.write(&js_dst, &v)?;
} }
@ -2558,8 +2584,11 @@ fn item_trait(
write_loading_content(w, "</div>"); write_loading_content(w, "</div>");
} }
} }
write!(w, r#"<script type="text/javascript">window.inlined_types=new Set({});</script>"#, write!(
as_json(&synthetic_types)); w,
r#"<script type="text/javascript">window.inlined_types=new Set({});</script>"#,
serde_json::to_string(&synthetic_types).unwrap(),
);
write!(w, r#"<script type="text/javascript" async write!(w, r#"<script type="text/javascript" async
src="{root_path}/implementors/{path}/{ty}.{name}.js"> src="{root_path}/implementors/{path}/{ty}.{name}.js">

View File

@ -8,7 +8,8 @@ use std::path::{Path, PathBuf};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use syntax::source_map::FileName; use syntax::source_map::FileName;
use syntax::symbol::sym; use syntax::symbol::sym;
use serialize::json::{ToJson, Json, as_json};
use serde::Serialize;
use super::{ItemType, IndexItem, IndexItemFunctionType, Impl, shorten, plain_summary_line}; use super::{ItemType, IndexItem, IndexItemFunctionType, Impl, shorten, plain_summary_line};
use super::{Type, RenderInfo}; use super::{Type, RenderInfo};
@ -544,7 +545,7 @@ fn extern_location(e: &clean::ExternalCrate, extern_url: Option<&str>, dst: &Pat
fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
let mut nodeid_to_pathid = FxHashMap::default(); let mut nodeid_to_pathid = FxHashMap::default();
let mut crate_items = Vec::with_capacity(cache.search_index.len()); let mut crate_items = Vec::with_capacity(cache.search_index.len());
let mut crate_paths = Vec::<Json>::new(); let mut crate_paths = vec![];
let Cache { ref mut search_index, let Cache { ref mut search_index,
ref orphan_impl_items, ref orphan_impl_items,
@ -581,7 +582,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
lastpathid += 1; lastpathid += 1;
let &(ref fqp, short) = paths.get(&nodeid).unwrap(); let &(ref fqp, short) = paths.get(&nodeid).unwrap();
crate_paths.push(((short as usize), fqp.last().unwrap().clone()).to_json()); crate_paths.push((short, fqp.last().unwrap().clone()));
pathid pathid
} }
}); });
@ -592,22 +593,33 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
} else { } else {
lastpath = item.path.clone(); lastpath = item.path.clone();
} }
crate_items.push(item.to_json()); crate_items.push(&*item);
} }
let crate_doc = krate.module.as_ref().map(|module| { let crate_doc = krate.module.as_ref().map(|module| {
shorten(plain_summary_line(module.doc_value())) shorten(plain_summary_line(module.doc_value()))
}).unwrap_or(String::new()); }).unwrap_or(String::new());
let mut crate_data = BTreeMap::new(); #[derive(Serialize)]
crate_data.insert("doc".to_owned(), Json::String(crate_doc)); struct CrateData<'a> {
crate_data.insert("i".to_owned(), Json::Array(crate_items)); doc: String,
crate_data.insert("p".to_owned(), Json::Array(crate_paths)); #[serde(rename = "i")]
items: Vec<&'a IndexItem>,
#[serde(rename = "p")]
paths: Vec<(ItemType, String)>,
}
// Collect the index into a string // Collect the index into a string
format!("searchIndex[{}] = {};", format!(
as_json(&krate.name), r#"searchIndex["{}"] = {};"#,
Json::Object(crate_data)) krate.name,
serde_json::to_string(&CrateData {
doc: crate_doc,
items: crate_items,
paths: crate_paths,
})
.unwrap()
)
} }
fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> { fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> {

View File

@ -35,7 +35,6 @@ extern crate rustc_parse;
extern crate rustc_target; extern crate rustc_target;
extern crate rustc_typeck; extern crate rustc_typeck;
extern crate rustc_lexer; extern crate rustc_lexer;
extern crate serialize;
extern crate syntax; extern crate syntax;
extern crate syntax_expand; extern crate syntax_expand;
extern crate syntax_pos; extern crate syntax_pos;