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