Optimize format to reduce crates-index.js file size

This commit is contained in:
Folyd 2019-11-19 18:59:07 +08:00
parent ce091b1b32
commit ec803c3bd0

View file

@ -3,8 +3,6 @@ use std::fs;
use std::path::Path; use std::path::Path;
use futures::future::join_all; use futures::future::join_all;
use serde::ser::Serialize;
use serde::Serializer;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use serde_json; use serde_json;
use tokio; use tokio;
@ -12,19 +10,23 @@ use tokio;
const API: &'static str = "https://crates.io/api/v1/crates?page={}&per_page=100&sort=downloads"; const API: &'static str = "https://crates.io/api/v1/crates?page={}&per_page=100&sort=downloads";
const CRATES_INDEX_PATH: &'static str = "../extension/crates-index.js"; const CRATES_INDEX_PATH: &'static str = "../extension/crates-index.js";
#[derive(Deserialize, Debug)] trait MinifiedUrl: Sized {
struct MinifiedUrl(String); fn minify_url(&self) -> Self;
}
impl Serialize for MinifiedUrl { impl MinifiedUrl for Option<String> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer { fn minify_url(&self) -> Self {
let url = self.0 match self {
.replace("http://", "") Some(value) => Some(value
.replace("https://", "") .replace("http://", "")
.replace("docs.rs", "D") .replace("https://", "")
.replace("crates.io", "C") .replace("docs.rs", "D")
.replace("github.io", "O") .replace("crates.io", "C")
.replace("github.com", "G"); .replace("github.io", "O")
serializer.serialize_str(&url) .replace("github.com", "G")
.replace("index.html", "I")),
None => None
}
} }
} }
@ -35,14 +37,10 @@ struct CrateApiResponse {
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
struct Crate { struct Crate {
#[serde(rename(serialize = "i"))]
id: String, id: String,
#[serde(rename(serialize = "d"))] description: Option<String>,
description: String, documentation: Option<String>,
#[serde(rename(serialize = "o"))] max_version: Option<String>,
documentation: Option<MinifiedUrl>,
#[serde(rename(serialize = "v"))]
max_version: String,
} }
async fn fetch_crates(page: u32) -> Result<Vec<Crate>, Box<dyn std::error::Error>> { async fn fetch_crates(page: u32) -> Result<Vec<Crate>, Box<dyn std::error::Error>> {
@ -53,9 +51,15 @@ async fn fetch_crates(page: u32) -> Result<Vec<Crate>, Box<dyn std::error::Error
async fn generate_javascript_crates_index(crates: Vec<Crate>) -> std::io::Result<()> { async fn generate_javascript_crates_index(crates: Vec<Crate>) -> std::io::Result<()> {
let mut contents = String::from("var N=null;"); let mut contents = String::from("var N=null;");
let crates_map: HashMap<String, Crate> = crates.into_iter() let crates_map: HashMap<String, [Option<String>; 3]> = crates.into_iter()
.map(|item| (item.id.to_lowercase(), item)) .map(|item| (item.id.to_lowercase(), [
.collect(); item.description.map(|mut value| {
value.truncate(100);
value
}),
item.documentation.minify_url(),
item.max_version
])).collect();
let mut crate_index = format!("var crateIndex={};", serde_json::to_string(&crates_map).unwrap()); let mut crate_index = format!("var crateIndex={};", serde_json::to_string(&crates_map).unwrap());
crate_index = crate_index.replace("null", "N"); crate_index = crate_index.replace("null", "N");
contents.push_str(&crate_index); contents.push_str(&crate_index);
@ -69,7 +73,7 @@ async fn generate_javascript_crates_index(crates: Vec<Crate>) -> std::io::Result
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let mut futures = vec![]; let mut futures = vec![];
for page in 1..=10 { for page in 1..=100 {
futures.push(fetch_crates(page)); futures.push(fetch_crates(page));
} }
let crates: Vec<Crate> = join_all(futures).await let crates: Vec<Crate> = join_all(futures).await