about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndy Russell <arussell123@gmail.com>2019-06-29 13:30:45 -0400
committerAndy Russell <arussell123@gmail.com>2019-12-12 16:33:25 -0500
commit94630d4c8bbf4c7c7e680210cd5d5f848c53aeaa (patch)
treefff2578ad5f6ccf4c540d40bb90a76a74e4c5c5b
parente9469a6aec2f49fa1e2ae670649f293866932253 (diff)
downloadrust-94630d4c8bbf4c7c7e680210cd5d5f848c53aeaa.tar.gz
rust-94630d4c8bbf4c7c7e680210cd5d5f848c53aeaa.zip
replace serialize with serde in rustdoc
-rw-r--r--Cargo.lock2
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/html/item_type.rs12
-rw-r--r--src/librustdoc/html/render.rs143
-rw-r--r--src/librustdoc/html/render/cache.rs34
-rw-r--r--src/librustdoc/lib.rs1
6 files changed, 125 insertions, 69 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 07a6c53c9c8..807304d11fd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3924,6 +3924,8 @@ dependencies = [
  "minifier",
  "pulldown-cmark 0.5.3",
  "rustc-rayon",
+ "serde",
+ "serde_json",
  "tempfile",
 ]
 
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index e3de7fe2049..f2822916d3c 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -12,4 +12,6 @@ path = "lib.rs"
 pulldown-cmark = { version = "0.5.3", default-features = false }
 minifier = "0.0.33"
 rayon = { version = "0.3.0", package = "rustc-rayon" }
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
 tempfile = "3"
diff --git a/src/librustdoc/html/item_type.rs b/src/librustdoc/html/item_type.rs
index f5e45924893..85f132378b1 100644
--- a/src/librustdoc/html/item_type.rs
+++ b/src/librustdoc/html/item_type.rs
@@ -1,7 +1,11 @@
 //! Item types.
 
 use std::fmt;
+
+use serde::{Serialize, Serializer};
+
 use syntax_pos::hygiene::MacroKind;
+
 use crate::clean;
 
 /// Item type. Corresponds to `clean::ItemEnum` variants.
@@ -45,6 +49,14 @@ pub enum ItemType {
     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 {
     fn from(item: &'a clean::Item) -> ItemType {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 86e5efbd7b3..e764b7ee527 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -31,7 +31,8 @@ use std::cmp::Ordering;
 use std::collections::{BTreeMap, VecDeque};
 use std::default::Default;
 use std::error;
-use std::fmt::{self, Formatter, Write as FmtWrite};
+
+use std::fmt::{self, Formatter, Write};
 use std::ffi::OsStr;
 use std::fs::{self, File};
 use std::io::prelude::*;
@@ -42,7 +43,8 @@ use std::sync::Arc;
 use std::rc::Rc;
 
 use errors;
-use serialize::json::{ToJson, Json, as_json};
+use serde::{Serialize, Serializer};
+use serde::ser::SerializeSeq;
 use syntax::ast;
 use syntax::edition::Edition;
 use syntax::print::pprust;
@@ -303,19 +305,22 @@ struct IndexItem {
     search_type: Option<IndexItemFunctionType>,
 }
 
-impl ToJson for IndexItem {
-    fn to_json(&self) -> Json {
+impl Serialize for IndexItem {
+    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());
 
-        let mut data = Vec::with_capacity(6);
-        data.push((self.ty as usize).to_json());
-        data.push(self.name.to_json());
-        data.push(self.path.to_json());
-        data.push(self.desc.to_json());
-        data.push(self.parent_idx.to_json());
-        data.push(self.search_type.to_json());
-
-        Json::Array(data)
+        (
+            self.ty,
+            &self.name,
+            &self.path,
+            &self.desc,
+            self.parent_idx,
+            &self.search_type,
+        )
+            .serialize(serializer)
     }
 }
 
@@ -326,18 +331,20 @@ struct Type {
     generics: Option<Vec<String>>,
 }
 
-impl ToJson for Type {
-    fn to_json(&self) -> Json {
-        match self.name {
-            Some(ref name) => {
-                let mut data = Vec::with_capacity(2);
-                data.push(name.to_json());
-                if let Some(ref generics) = self.generics {
-                    data.push(generics.to_json());
-                }
-                Json::Array(data)
+impl Serialize for Type {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        if let Some(name) = &self.name {
+            let mut seq = serializer.serialize_seq(None)?;
+            seq.serialize_element(&name)?;
+            if let Some(generics) = &self.generics {
+                seq.serialize_element(&generics)?;
             }
-            None => Json::Null,
+            seq.end()
+        } else {
+            serializer.serialize_none()
         }
     }
 }
@@ -349,26 +356,29 @@ struct IndexItemFunctionType {
     output: Option<Vec<Type>>,
 }
 
-impl ToJson for IndexItemFunctionType {
-    fn to_json(&self) -> Json {
+impl Serialize for IndexItemFunctionType {
+    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 mut iter = self.inputs.iter();
         if match self.output {
             Some(ref output) => iter.chain(output.iter()).any(|ref i| i.name.is_none()),
             None => iter.any(|ref i| i.name.is_none()),
         } {
-            Json::Null
+            serializer.serialize_none()
         } else {
-            let mut data = Vec::with_capacity(2);
-            data.push(self.inputs.to_json());
-            if let Some(ref output) = self.output {
+            let mut seq = serializer.serialize_seq(None)?;
+            seq.serialize_element(&self.inputs)?;
+            if let Some(output) = &self.output {
                 if output.len() > 1 {
-                    data.push(output.to_json());
+                    seq.serialize_element(&output)?;
                 } 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
     // at the beginning of the html files into another js file.
     let theme_js = format!(
-r#"var themes = document.getElementById("theme-choices");
+        r#"var themes = document.getElementById("theme-choices");
 var themePicker = document.getElementById("theme-picker");
 
 function showThemeButtonState() {{
@@ -642,8 +652,8 @@ themePicker.onblur = handleThemeButtonsBlur;
     }};
     but.onblur = handleThemeButtonsBlur;
     themes.appendChild(but);
-}});"#,
-                 as_json(&themes));
+}});"#, serde_json::to_string(&themes).unwrap());
+
     write_minify(&cx.shared.fs, cx.path("theme.js"),
                  &theme_js,
                  options.enable_minification)?;
@@ -932,32 +942,48 @@ themePicker.onblur = handleThemeButtonsBlur;
             }
         };
 
-        let mut have_impls = false;
-        let mut implementors = format!(r#"implementors["{}"] = ["#, krate.name);
-        for imp in imps {
-            // 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 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();
+        #[derive(Serialize)]
+        struct Implementor {
+            text: String,
+            synthetic: bool,
+            types: Vec<String>,
         }
-        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
         // documented locally though we always create the file to avoid dead
         // links.
-        if !have_impls && !cx.cache.paths.contains_key(&did) {
+        if implementors.is_empty() && !cx.cache.paths.contains_key(&did) {
             continue;
         }
 
+        let implementors = format!(
+            r#"implementors["{}"] = {};"#,
+            krate.name,
+            serde_json::to_string(&implementors).unwrap()
+        );
+
         let mut mydst = dst.clone();
         for part in &remote_path[..remote_path.len() - 1] {
             mydst.push(part);
@@ -1456,7 +1482,7 @@ impl Context {
             if !self.render_redirect_pages {
                 let items = self.build_sidebar_items(&m);
                 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)?;
             }
 
@@ -2558,8 +2584,11 @@ fn item_trait(
             write_loading_content(w, "</div>");
         }
     }
-    write!(w, r#"<script type="text/javascript">window.inlined_types=new Set({});</script>"#,
-           as_json(&synthetic_types));
+    write!(
+        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
                          src="{root_path}/implementors/{path}/{ty}.{name}.js">
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index 65dd119c27c..d80facf4704 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -8,7 +8,8 @@ use std::path::{Path, PathBuf};
 use std::collections::BTreeMap;
 use syntax::source_map::FileName;
 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::{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 {
     let mut nodeid_to_pathid = FxHashMap::default();
     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,
                 ref orphan_impl_items,
@@ -581,7 +582,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
                 lastpathid += 1;
 
                 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
             }
         });
@@ -592,22 +593,33 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
         } else {
             lastpath = item.path.clone();
         }
-        crate_items.push(item.to_json());
+        crate_items.push(&*item);
     }
 
     let crate_doc = krate.module.as_ref().map(|module| {
         shorten(plain_summary_line(module.doc_value()))
     }).unwrap_or(String::new());
 
-    let mut crate_data = BTreeMap::new();
-    crate_data.insert("doc".to_owned(), Json::String(crate_doc));
-    crate_data.insert("i".to_owned(), Json::Array(crate_items));
-    crate_data.insert("p".to_owned(), Json::Array(crate_paths));
+    #[derive(Serialize)]
+    struct CrateData<'a> {
+        doc: String,
+        #[serde(rename = "i")]
+        items: Vec<&'a IndexItem>,
+        #[serde(rename = "p")]
+        paths: Vec<(ItemType, String)>,
+    }
 
     // Collect the index into a string
-    format!("searchIndex[{}] = {};",
-            as_json(&krate.name),
-            Json::Object(crate_data))
+    format!(
+        r#"searchIndex["{}"] = {};"#,
+        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> {
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index a4be3dee938..a7ef428bc85 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -35,7 +35,6 @@ extern crate rustc_parse;
 extern crate rustc_target;
 extern crate rustc_typeck;
 extern crate rustc_lexer;
-extern crate serialize;
 extern crate syntax;
 extern crate syntax_expand;
 extern crate syntax_pos;