summaryrefslogtreecommitdiffstats
path: root/categories/src
diff options
context:
space:
mode:
authorKornel <kornel@geekhood.net>2019-01-19 12:20:24 +0000
committerKornel <kornel@geekhood.net>2019-01-19 12:20:43 +0000
commit652bc2e7131d8720e77da40344803449ffd37d45 (patch)
tree5b5b07b05d46b5220d8c39f1e301f6a4e46367e9 /categories/src
parent32d263ce8488cc19613af043c2c3034bd31731a9 (diff)
Move to subdir
Diffstat (limited to 'categories/src')
-rw-r--r--categories/src/categories.rs165
-rw-r--r--categories/src/categories.toml707
-rw-r--r--categories/src/tuning.rs903
3 files changed, 1775 insertions, 0 deletions
diff --git a/categories/src/categories.rs b/categories/src/categories.rs
new file mode 100644
index 0000000..fcc3aeb
--- /dev/null
+++ b/categories/src/categories.rs
@@ -0,0 +1,165 @@
+use toml;
+
+#[macro_use] extern crate serde_derive;
+#[macro_use] extern crate lazy_static;
+#[macro_use] extern crate quick_error;
+
+use toml::value::{Value, Table};
+use std::collections::BTreeMap;
+use std::borrow::Cow;
+
+mod tuning;
+pub use crate::tuning::*;
+
+const CATEGORIES_TOML: &[u8] = include_bytes!("categories.toml");
+
+#[derive(Debug, Clone)]
+pub struct Categories {
+ pub root: CategoryMap,
+}
+
+#[derive(Debug, Clone, Deserialize)]
+pub struct Category {
+ pub name: String,
+ pub description: String,
+ #[serde(rename = "short-description")]
+ pub short_description: String,
+ #[serde(rename = "standalone-name")]
+ pub standalone_name: Option<String>,
+ pub title: String,
+ pub slug: String,
+ pub sub: CategoryMap,
+ pub siblings: Vec<String>,
+}
+
+pub type CategoryMap = BTreeMap<String, Category>;
+pub type CResult<T> = Result<T, CatError>;
+
+quick_error! {
+ #[derive(Debug, Clone)]
+ pub enum CatError {
+ MissingField {}
+ Parse(err: toml::de::Error) {
+ display("Categories parse error: {}", err)
+ from()
+ cause(err)
+ }
+ }
+}
+
+lazy_static! {
+ pub static ref CATEGORIES: Categories = { Categories::new().expect("built-in categories") };
+}
+
+impl Categories {
+ fn new() -> CResult<Self> {
+ Ok(Self {
+ root: Self::categories_from_table("", toml::from_slice(CATEGORIES_TOML)?)?
+ })
+ }
+
+ pub fn from_slug<S: AsRef<str>>(&self, slug: S) -> impl Iterator<Item = &Category> {
+ let mut out = Vec::new();
+ let mut cats = &self.root;
+ for name in slug.as_ref().split("::") {
+ match cats.get(name) {
+ Some(cat) => {
+ cats = &cat.sub;
+ out.push(cat);
+ },
+ None => break,
+ }
+ }
+ out.into_iter()
+ }
+
+ fn categories_from_table(full_slug_start: &str, toml: Table) -> CResult<CategoryMap> {
+ toml.into_iter().map(|(slug, details)| {
+ let mut details: Table = details.try_into()?;
+ let name = details.remove("name").ok_or(CatError::MissingField)?.try_into()?;
+ let description = details.remove("description").ok_or(CatError::MissingField)?.try_into()?;
+ let short_description = details.remove("short-description").ok_or(CatError::MissingField)?.try_into()?;
+ let title = details.remove("title").ok_or(CatError::MissingField)?.try_into()?;
+ let standalone_name = details.remove("standalone-name").and_then(|v| v.try_into().ok());
+ let siblings = details.remove("siblings").and_then(|v| v.try_into().ok()).unwrap_or_default();
+
+ let mut full_slug = String::with_capacity(full_slug_start.len()+2+slug.len());
+ if full_slug_start != "" {
+ full_slug.push_str(full_slug_start);
+ full_slug.push_str("::");
+ }
+ full_slug.push_str(&slug);
+
+ let sub = if let Some(Value::Table(table)) = details.remove("categories") {
+ Self::categories_from_table(&full_slug, table)?
+ } else {
+ CategoryMap::new()
+ };
+ Ok((slug, Category {
+ name,
+ title,
+ short_description,
+ standalone_name,
+ description,
+ slug: full_slug,
+ sub,
+ siblings,
+ }))
+ }).collect()
+ }
+
+ pub fn fixed_category_slugs(cats: &[String]) -> Vec<Cow<'_, str>> {
+ let mut cats = cats.iter().enumerate().filter_map(|(idx, s)| {
+ if s.len() < 2 {
+ return None;
+ }
+ if s == "external-ffi-bindings" { // We pretend it doesn't exist
+ return None;
+ }
+ if s == "api-bindings" { // We pretend it doesn't exist
+ return None;
+ }
+ let mut chars = s.chars().peekable();
+ while let Some(cur) = chars.next() {
+ // look for a:b instead of a::b
+ if cur == ':' {
+ if chars.peek().map_or(false, |&c| c == ':') {
+ chars.next(); // OK, skip second ':'
+ continue;
+ }
+ }
+ if cur == '-' || cur.is_ascii_lowercase() || cur.is_ascii_digit() {
+ continue;
+ }
+
+ // bad syntax! Fix!
+ let slug = s.to_ascii_lowercase().split(':').filter(|s| !s.is_empty()).collect::<Vec<_>>().join("::");
+ if s.is_empty() {
+ return None;
+ }
+ let depth = slug.split("::").count();
+ return Some((depth, idx, slug.into()));
+ }
+ let depth = s.split("::").count();
+ Some((depth, idx, Cow::Borrowed(s.as_ref())))
+ }).collect::<Vec<_>>();
+
+ // depth, then original order
+ cats.sort_by(|a, b| b.0.cmp(&a.0).then(a.1.cmp(&b.1)));
+
+ cats.into_iter().map(|(_, _, c)| c).collect()
+ }
+}
+
+impl Category {
+ pub fn standalone_name(&self) -> &str {
+ self.standalone_name.as_ref().unwrap_or(&self.name).as_str()
+ }
+}
+
+#[test]
+fn cat() {
+ Categories::new().expect("categories").root.get("parsing").expect("parsing");
+
+ CATEGORIES.root.get("development-tools").expect("development-tools").sub.get("build-utils").expect("build-utils");
+}
diff --git a/categories/src/categories.toml b/categories/src/categories.toml
new file mode 100644
index 0000000..ac85f2f
--- /dev/null
+++ b/categories/src/categories.toml
@@ -0,0 +1,707 @@
+# This is where the categories available on crates.io are defined. To propose
+# a change to the categories, send a pull request with your change made to this
+# file.
+#
+# For help with TOML, see: https://github.com/toml-lang/toml
+#
+# Format:
+#
+# ```toml
+# [slug]
+# name = "Display name"
+# description = "Give an idea of the crates that belong in this category."
+#
+# [slug.categories.subcategory-slug]
+# name = "Subcategory display name, not including parent category display name"
+# description = "Give an idea of the crates that belong in this subcategory."
+# ```
+#
+# Notes:
+# - Slugs are the primary identifier. If you make a change to a category's slug,
+# crates that have been published with that slug will need to be updated to
+# use the new slug in order to stay in that category. If you only change
+# names and descriptions, those attributes CAN be updated without affecting
+# crates in that category.
+# - Slugs are used in the path of URLs, so they should not contain spaces, `/`,
+# `@`, `:`, or `.`. They should be all lowercase.
+#
+
+[algorithms]
+name = "Algorithms"
+title = "Rust implementation"
+description = """
+Rust implementations of core algorithms such as hashing, sorting, \
+searching, and more.\
+"""
+short-description = """
+Core algorithms such as hashing, sorting and searching.
+"""
+
+# [api-bindings]
+# name = "API bindings"
+# title = "Rust API bindings"
+# description = """
+# Idiomatic wrappers of specific APIs for convenient access from \
+# Rust. Includes HTTP API wrappers as well. Non-idiomatic or unsafe \
+# bindings can be found in External FFI bindings.\
+# """
+# short-description = """
+# Idiomatic wrappers of C library APIs for convenient access from Rust."""
+
+[asynchronous]
+name = "Asynchronous"
+title = "async Rust library"
+description = """
+Crates to help you deal with events independently of the main program \
+flow, using techniques like futures, promises, waiting, or eventing.\
+"""
+short-description = """
+Async program flow using techniques like futures, promises, waiting, or eventing."""
+
+[authentication]
+name = "Authentication"
+title = "Rust auth library"
+description = """
+Crates to help with the process of confirming identities.\
+"""
+short-description = """
+Help with the process of confirming identities."""
+
+[caching]
+name = "Caching"
+title = "Rust caching library"
+description = """
+Crates to store the results of previous computations in order to reuse \
+the results.\
+"""
+short-description = """
+Store the results of previous computations."""
+
+[command-line-interface]
+name = "Command-line interface"
+title = "CLI for Rust"
+description = """
+Crates to help create command line interfaces, such as argument \
+parsers, line-editing, or output coloring and formatting.\
+"""
+short-description = """
+Argument parsers, line-editing, or output coloring and formatting."""
+
+[command-line-utilities]
+name = "Command line utilities"
+title = "Rust command line util"
+description = """
+Applications to run at the command line.\
+"""
+short-description = """
+Applications to run at the command line."""
+
+[compression]
+name = "Compression"
+title = "Rust compression library"
+description = """
+Algorithms for making data smaller.\
+"""
+short-description = """
+Algorithms for making data smaller."""
+
+[config]
+name = "Configuration"
+title = "Rust config library"
+description = """
+Crates to facilitate configuration management for applications.\
+"""
+short-description = """
+Configuration management for applications."""
+
+[concurrency]
+name = "Concurrency"
+title = "Rust concurrency library"
+description = """
+Crates for implementing concurrent and parallel computation.\
+"""
+short-description = """
+Implementing concurrent and parallel computation."""
+
+[cryptography]
+name = "Cryptography"
+title = "Rust crypto library"
+description = """
+Algorithms intended for securing data.\
+"""
+short-description = """
+Algorithms intended for securing data."""
+
+[cryptography.categories.cryptocurrencies]
+# fake, like the money
+name = "Cryptocurrencies"
+title = "cryptocurrencies in Rust"
+description = """
+Libraries and tools for digital currencies, and distributed ledgers.\
+"""
+short-description = "Coins, blockchains and wallets."
+
+[database]
+name = "Database interfaces"
+title = "db interface for Rust"
+description = """
+Crates to interface with database management systems.\
+"""
+short-description = """
+Interface with database management systems."""
+siblings = ["database-implementations"]
+
+[database-implementations]
+name = "Database implementations"
+title = "Rust database"
+description = """
+Databases allow clients to store and query large amounts of data in an \
+efficient manner. This category is for database management systems \
+implemented in Rust.\
+"""
+short-description = """
+Database management systems implemented in Rust."""
+siblings = ["database"]
+
+[data-structures]
+name = "Data structures"
+title = "data structures in Rust"
+description = """
+Rust implementations of particular ways of organizing data suited for \
+specific purposes.\
+"""
+short-description = """
+Rust implementations of data structures for specific purposes."""
+
+[date-and-time]
+name = "Date and time"
+title = "Rust date/time library"
+description = """
+Crates to manage the inherent complexity of dealing with the fourth \
+dimension.\
+"""
+short-description = """
+Dealing with the fourth dimension."""
+
+[development-tools]
+name = "Development tools"
+title = "Rust dev tool"
+description = """
+Crates that provide developer-facing features such as testing, debugging, \
+linting, performance profiling, autocompletion, formatting, and more.\
+"""
+short-description = """
+Testing, debugging, linting, performance profiling, autocompletion, formatting, and more."""
+
+[development-tools.categories.build-utils]
+name = "Build Utils"
+title = "Rust build util"
+description = """
+Utilities for build scripts and other build time steps.\
+"""
+short-description = """
+Utilities for build scripts and other build time steps."""
+
+[development-tools.categories.cargo-plugins]
+name = "Cargo plugins"
+title = "Cargo plug-in"
+description = """
+Subcommands that extend the capabilities of Cargo.\
+"""
+short-description = """
+Subcommands that extend the capabilities of Cargo."""
+
+[development-tools.categories.debugging]
+name = "Debugging"
+title = "for debugging in Rust"
+description = """
+Crates to help you figure out what is going on with your code such as \
+logging, tracing, or assertions.\
+"""
+short-description = """
+Figure out what is going on with your code via logging, tracing, or assertions."""
+
+[development-tools.categories.ffi]
+name = "FFI"
+title = "C interface for Rust"
+description = """
+Crates to help you better interface with other languages. This \
+includes binding generators and helpful language constructs.\
+"""
+short-description = """
+Interface with other languages. Includes binding generators and helpful language constructs."""
+
+[development-tools.categories.procedural-macro-helpers]
+name = "Procedural macro helpers"
+title = "Rust proc macro helper"
+description = """
+Crates to help you write procedural macros in Rust.
+"""
+short-description = """
+Extend Rust language with procedural macros.
+"""
+
+[development-tools.categories.profiling]
+name = "Profiling"
+title = "profiling in Rust"
+description = """
+Crates to help you figure out the performance of your code.\
+"""
+short-description = """
+Figure out the performance of your code."""
+
+[development-tools.categories.testing]
+name = "Testing"
+title = "Rust testing library"
+description = """
+Crates to help you verify the correctness of your code.\
+"""
+short-description = """
+Verify the correctness of your code."""
+
+[email]
+name = "Email"
+title = "Rust email library"
+description = """
+Crates to help with Sending, receiving, formatting, and parsing email.\
+"""
+short-description = """
+Sending, receiving, formatting, and parsing email."""
+
+[embedded]
+name = "Embedded development"
+title = "embedded dev in Rust"
+description = """
+Crates that are primarily useful on embedded devices or \
+without an operating system.
+"""
+short-description = """
+For embedded devices or devices without an operating system.
+"""
+siblings = ["hardware-support", "no-std"]
+
+[emulators]
+name = "Emulators"
+title = "emulator in Rust"
+description = """
+Emulators allow one computer to behave like another, often to allow \
+running software that is not natively available on the host \
+computer. Video game systems are commonly emulated.\
+"""
+short-description = """
+Run software or games not available natively on the host computer."""
+
+[encoding]
+name = "Encoding"
+standalone-name = "Encoding data"
+title = "Rust data encoding library"
+description = """
+Encoding and/or decoding data from one data format to another.\
+"""
+short-description = """
+Encoding and/or decoding data from one data format to another."""
+
+# [external-ffi-bindings]
+# name = "External FFI bindings"
+# title = "Rust bindings for external library"
+# description = """
+# Direct Rust FFI bindings to libraries written in other languages; \
+# often denoted by a -sys suffix. Safe and idiomatic wrappers are in \
+# the API bindings category.
+# """
+# short-description = """
+# Direct Rust FFI bindings to libraries written in other languages
+# """
+
+[filesystem]
+name = "Filesystem"
+title = "Rust filesystem library"
+description = """
+Crates for dealing with files and filesystems.\
+"""
+short-description = """
+Crates for dealing with files and filesystems."""
+
+[game-engines]
+name = "Game engines"
+title = "Rust game engine"
+description = """
+Crates for creating games.\
+"""
+short-description = """
+Crates for creating games."""
+
+[games]
+name = "Games"
+title = "game in Rust"
+description = """
+Applications for fun and entertainment. If Rust the video game were \
+implemented in Rust the programming language, it would belong in this \
+category. Libraries to help create video games are in the \
+Game engines category.\
+"""
+short-description = """
+Fun and entertainment. Games implemented in the Rust programming language."""
+
+[gui]
+name = "GUI"
+title = "Rust GUI library"
+description = """
+Crates to help you create a graphical user interface.\
+"""
+short-description = """
+Create a graphical user interface."""
+
+[hardware-support]
+name = "Hardware support"
+title = "Rust HW library"
+description = """
+Crates to interface with specific CPU or other hardware features.\
+"""
+short-description = """
+Interface with specific CPU or other hardware features."""
+siblings = ["embedded"]
+
+[internationalization]
+name = "Internationalization (i18n)"
+title = "Rust i18n library"
+description = """
+Crates to develop software adapting to various \
+languages and regions. Including localization (L10n) software.\
+"""
+short-description = """
+and localization (l10n). Develop software for various languages and regions."""
+
+# merged into internationalization
+# [localization]
+# name = "Localization (L10n)"
+# title = "Rust localization"
+# description = """
+# Crates to help adapting internationalized software to specific \
+# languages and regions.\
+# """
+# short-description = """
+# Internationalizing software to specific languages and regions."""
+
+[memory-management]
+name = "Memory management"
+title = "Rust memory management library"
+description = """
+Crates to help with allocation, memory mapping, garbage collection, \
+reference counting, or interfaces to foreign memory managers.\
+"""
+short-description = """
+Allocation, memory mapping, garbage collection, reference counting, or interfaces to foreign memory managers."""
+
+[multimedia]
+name = "Multimedia"
+title = "multimedia in Rust"
+description = """
+Crates that provide audio, video, and image processing or rendering \
+engines.\
+"""
+short-description = """
+Audio, video, and image processing or rendering engines."""
+
+[multimedia.categories.audio]
+name = "Audio"
+title = "Rust audio library"
+description = """
+Crates that record, output, or process audio.
+"""
+short-description = """
+Record, output, or process audio.
+"""
+
+[multimedia.categories.video]
+name = "Video"
+title = "Rust video library"
+description = """
+Crates that record, output, or process video.
+"""
+short-description = """
+Record, output, or process video.
+"""
+
+[multimedia.categories.images]
+name = "Images"
+title = "Rust image library"
+description = """
+Crates that process or build images.
+"""
+short-description = """
+Process or build images.
+"""
+
+[multimedia.categories.encoding]
+name = "Encoding"
+standalone-name = "Encoding media"
+title = "Rust media encoding library"
+description = """
+Crates that encode or decode binary data in multimedia formats.
+"""
+short-description = """
+Encode or decode binary data in multimedia formats.
+"""
+
+[network-programming]
+name = "Network programming"
+title = "Rust network library"
+description = """
+Crates dealing with higher-level network protocols such as FTP, HTTP, \
+or SSH, or lower-level network protocols such as TCP or UDP.\
+"""
+short-description = """
+Network protocols such as FTP, HTTP, or SSH, or lower-level TCP or UDP."""
+siblings = ["authentication", "email"]
+
+[no-std]
+name = "No standard library"
+title = "bare metal library for Rust"
+description = """
+Crates that are able to function without the Rust standard library.
+"""
+short-description = """
+Libraries that function without the Rust standard library.
+"""
+siblings = ["embedded"]
+
+[os]
+name = "Operating systems"
+title = "Rust OS-specific library"
+description = """
+Bindings to operating system-specific APIs.\
+"""
+short-description = """
+Bindings to operating system-specific APIs."""
+
+[os.categories.macos-apis]
+name = "macOS APIs"
+title = "Rust API for macOS"
+description = """
+Bindings to macOS-specific APIs.\
+"""
+short-description = """
+Bindings to macOS-specific APIs."""
+
+[os.categories.unix-apis]
+name = "Unix APIs"
+title = "Rust API for Unix"
+description = """
+Bindings to Unix-specific APIs.\
+"""
+short-description = """
+Bindings to Unix-specific APIs."""
+
+[os.categories.windows-apis]
+name = "Windows APIs"
+title = "Rust API Windows"
+description = """
+Bindings to Windows-specific APIs.\
+"""
+short-description = """
+Bindings to Windows-specific APIs."""
+
+[parser-implementations]
+name = "Parser implementations"
+title = "Rust parser"
+description = """
+Parsers implemented for particular formats or languages.\
+"""
+short-description = """
+Parse data formats or languages."""
+siblings = ["parsing"]
+
+[parsing]
+name = "Parsing tools"
+title = "Parser tooling"
+description = """
+Write or generate parsers of binary and text formats. \
+Format-specific parsers belong in other, more specific categories.
+"""
+short-description = """
+Parsing tools and parser generators."""
+siblings = ["parser-implementations"]
+
+[rendering]
+name = "Rendering"
+title = "graphics rendering in Rust"
+description = """
+Real-time or offline rendering of 2D or 3D graphics, \
+usually with the help of a graphics card.\
+"""
+short-description = """
+Real-time or offline rendering of 2D or 3D graphics, usually on a GPU."""
+
+[rendering.categories.engine]
+name = "Rendering engine"
+title = "Rust rendering engine"
+description = """
+High-level solutions for rendering on the screen.\
+"""
+short-description = """
+High-level solutions for rendering on the screen."""
+
+[rendering.categories.graphics-api]
+name = "Graphics APIs"
+title = "Rust gfx library"
+description = """
+Crates that provide direct access to the hardware's or the operating \
+system's rendering capabilities.\
+"""
+short-description = """
+Direct access to the hardware's or the operating system's rendering capabilities."""
+
+[rendering.categories.data-formats]
+name = "Data formats"
+standalone-name = "Gfx data formats"
+title = "data format for Rust"
+description = """
+Loading and parsing of data formats related to 2D or 3D rendering, like \
+3D models or animation sheets.\
+"""
+short-description = """
+Loading and parsing of data for 2D/3D rendering, like 3D models or animations."""
+
+[rust-patterns]
+name = "Rust patterns"
+title = "Rust language library"
+description = """
+Shared solutions for particular situations specific to programming in \
+Rust.\
+"""
+short-description = """
+Shared solutions for particular situations specific to programming in Rust."""
+
+[science]
+name = "Science"
+title = "Rust library"
+description = """
+Crates related to solving problems involving math, physics, chemistry, \
+biology, machine learning, geoscience, and other scientific fields.\
+"""
+short-description = """
+Solving problems involving math, physics, and other scientific fields."""
+
+[science.categories.math]
+# fake
+name = "Math"
+title = "Rust math library"
+description = """
+Crates related to solving mathematical problems.\
+"""
+short-description = """
+Solving problems involving math and logic."""
+
+[science.categories.ml]
+# fake
+name = "Machine learning"
+title = "ML/AI/statistics in Rust"
+description = """
+Artificial intelligence, neural networks, deep learning, recommendation systems, and statistics.\
+"""
+short-description = """AI, ML, NN, etc."""
+
+[simulation]
+name = "Simulation"
+title = "Rust simulation library"
+description = """
+Crates used to model or construct models for some activity, e.g. to \
+simulate a networking protocol.\
+"""
+short-description = """
+Model or construct models for some activity, e.g. to simulate a networking protocol."""
+
+[template-engine]
+name = "Template engine"
+title = "Rust template engine"
+description = """
+Crates designed to combine templates with data to produce result \
+documents, usually with an emphasis on processing text.\
+"""
+short-description = """
+Combine templates with data to produce documents, usually with an emphasis on processing text."""
+
+[text-editors]
+name = "Text editors"
+title = "Rust text editor"
+description = """
+Applications for editing text.\
+"""
+short-description = """
+Applications for editing text."""
+
+[text-processing]
+name = "Text processing"
+title = "Rust text processing library"
+description = """
+Crates to deal with the complexities of human language when expressed \
+in textual form.\
+"""
+short-description = """
+Deal with the complexities of human language when expressed in textual form."""
+
+[value-formatting]
+name = "Value formatting"
+title = "Rust formatting library"
+description = """
+Crates to allow an application to format values for display to a user, \
+potentially adapting the display to various languages and regions.\
+"""
+short-description = """
+Format values for display to a user, potentially adapting the display to various languages and regions."""
+
+[visualization]
+name = "Visualization"
+title = "Rust data vis library"
+description = """
+Ways to view data, such as plotting or graphing.\
+"""
+short-description = """
+Ways to view data, such as plotting or graphing."""
+
+[wasm]
+name = "WebAssembly"
+title = "WebAssembly in Rust"
+description = """
+Crates for use when targeting WebAssembly, or for manipulating WebAssembly.\
+"""
+short-description = """
+Targeting or manipulating WebAssembly."""
+
+[web-programming]
+name = "Web programming"
+title = "Rust web dev library"
+description = """
+Crates to create applications for the web.\
+"""
+short-description = """
+Create applications for the Web."""
+siblings = ["wasm"]
+
+[web-programming.categories.http-client]
+name = "HTTP client"
+title = "Rust HTTP client"
+description = """
+Crates to make HTTP network requests.\
+"""
+short-description = """
+Make HTTP network requests."""
+
+[web-programming.categories.http-server]
+name = "HTTP server"
+title = "Rust HTTP server"
+description = """
+Crates to serve data over HTTP.\
+"""
+short-description = """
+Serve data over HTTP."""
+
+[web-programming.categories.websocket]
+name = "WebSocket"
+title = "WebSocket library in Rust"
+description = """
+Crates to communicate over the WebSocket protocol.\
+"""
+short-description = """
+Communicate over the WebSocket protocol."""
diff --git a/categories/src/tuning.rs b/categories/src/tuning.rs
new file mode 100644
index 0000000..f12474d
--- /dev/null
+++ b/categories/src/tuning.rs
@@ -0,0 +1,903 @@
+use crate::CATEGORIES;
+use std::collections::HashMap;
+use std::collections::HashSet;
+
+lazy_static! {
+ /// If one is present, adjust score of a category
+ ///
+ /// `keyword: [(slug, multiply, add)]`
+ pub(crate) static ref KEYWORD_CATEGORIES: Vec<(Cond, &'static [(&'static str, f64, f64)])> = [
+ (Cond::Any(&["no-std", "no_std"]), &[("no-std", 1.4, 0.15), ("command-line-utilities", 0.5, 0.), ("cryptography::cryptocurrencies", 0.9, 0.)][..]),
+ // derived from features
+ (Cond::Any(&["feature:no_std", "feature:no-std", "feature:std", "heapless"]), &[("no-std", 1.2, 0.)]),
+ (Cond::Any(&["print", "font", "parsing", "hashmap", "money", "flags", "data-structure", "cache", "macros", "wasm", "emulator", "hash"]), &[("no-std", 0.6, 0.)]),
+
+ (Cond::Any(&["winsdk", "winrt", "directx", "dll", "win32", "winutil", "msdos", "winapi"]),
+ &[("os::windows-apis", 1.5, 0.1), ("parser-implementations", 0.9, 0.), ("text-processing", 0.9, 0.), ("text-editors", 0.8, 0.), ("no-std", 0.9, 0.)]),
+ (Cond::All(&["windows", "ffi"]), &[("os::windows-apis", 1.1, 0.1), ("memory-management", 0.9, 0.)]),
+ (Cond::Any(&["windows"]), &[("os::windows-apis", 1.1, 0.1), ("text-processing", 0.8, 0.)]),
+ (Cond::All(&["ffi", "winsdk"]), &[("os::windows-apis", 1.9, 0.5), ("no-std", 0.5, 0.), ("science::math", 0.9, 0.)]),
+ (Cond::All(&["ffi", "windows"]), &[("os::windows-apis", 1.2, 0.2)]),
+ (Cond::Any(&["winauth", "ntlm"]), &[("os::windows-apis", 1.25, 0.2), ("authentication", 1.3, 0.2)]),
+
+ (Cond::Any(&["windows", "winsdk", "win32", "activex"]), &[("os::macos-apis", 0., 0.), ("os::unix-apis", 0., 0.), ("science::math", 0.8, 0.), ("memory-management", 0.9, 0.)]),
+ (Cond::Any(&["macos", "mac", "osx", "ios", "cocoa", "erlang"]), &[("os::windows-apis", 0., 0.), ("no-std", 0.01, 0.)]),
+ (Cond::Any(&["macos", "mac", "osx", "cocoa", "mach-o", "uikit", "appkit"]), &[("os::macos-apis", 1.4, 0.2), ("science::math", 0.75, 0.)]),
+ (Cond::All(&["os", "x"]), &[("os::macos-apis", 1.2, 0.)]),
+ (Cond::Any(&["dmg"]), &[("os::macos-apis", 1.2, 0.1)]),
+ (Cond::All(&["core", "foundation"]), &[("os::macos-apis", 1.2, 0.1), ("os", 0.8, 0.), ("concurrency", 0.3, 0.)]),
+ (Cond::Any(&["corefoundation"]), &[("os::macos-apis", 1.2, 0.1), ("os", 0.8, 0.), ("concurrency", 0.3, 0.)]),
+ (Cond::Any(&["core"]), &[("os::macos-apis", 1.05, 0.), ("os", 0.95, 0.), ("concurrency", 0.9, 0.)]),
+ (Cond::Any(&["keycode", "platforms", "platform", "processor", "child", "system", "executable", "processes"]),
+ &[("os", 1.2, 0.1), ("network-programming", 0.7, 0.), ("cryptography", 0.5, 0.), ("date-and-time", 0.8, 0.),
+ ("games", 0.7, 0.), ("authentication", 0.6, 0.), ("internationalization", 0.7, 0.)]),
+ (Cond::Any(&["mount", "package", "uname", "boot", "kernel"]),
+ &[("os", 1.2, 0.1), ("network-programming", 0.7, 0.), ("cryptography", 0.5, 0.), ("date-and-time", 0.8, 0.),
+ ("games", 0.7, 0.), ("multimedia", 0.8, 0.), ("multimedia::video", 0.7, 0.), ("multimedia::encoding", 0.8, 0.),
+ ("rendering::engine", 0.8, 0.), ("rendering", 0.8, 0.), ("authentication", 0.6, 0.), ("internationalization", 0.7, 0.)]),
+ (Cond::Any(&["dependency-manager", "package-manager", "clipboard", "process", "bootloader", "taskbar", "microkernel", "multiboot"]),
+ &[("os", 1.2, 0.1), ("network-programming", 0.8, 0.), ("multimedia::video", 0.7, 0.), ("multimedia::encoding", 0.5, 0.), ("cryptography", 0.7, 0.), ("filesystem", 0.8, 0.), ("games", 0.2, 0.), ("authentication", 0.6, 0.),
+ ("internationalization", 0.7, 0.)]),
+ (Cond::All(&["package", "manager"]), &[("os", 1.1, 0.), ("development-tools", 1.2, 0.1)]),
+ (Cond::All(&["device", "configuration"]), &[("os", 1.2, 0.2), ("config", 0.9, 0.)]),
+ (Cond::Any(&["os", "hostname"]), &[("os", 1.2, 0.1), ("data-structures", 0.6, 0.)]),
+ (Cond::All(&["shared", "library"]), &[("os", 1.2, 0.2), ("no-std", 0.3, 0.), ("config", 0.9, 0.)]),
+ (Cond::Any(&["dlopen"]), &[("os", 1.2, 0.2), ("no-std", 0.3, 0.), ("config", 0.8, 0.)]),
+ (Cond::Any(&["library"]), &[("games", 0.8, 0.), ("development-tools::cargo-plugins", 0.8, 0.)]),
+ (Cond::Any(&["ios", "objective-c"]), &[("os::macos-apis", 1.2, 0.1), ("no-std", 0.1, 0.)]),
+ (Cond::NotAny(&["ios", "objective-c", "objc", "objrs", "hfs", "osx", "os-x", "dylib", "mach", "xcode", "uikit", "appkit", "metal", "foundation", "macos", "mac", "apple", "cocoa", "core"]), &[("os::macos-apis", 0.8, 0.)]),
+ (Cond::Any(&["linux", "freebsd", "openbsd", "netbsd", "arch-linux", "pacman", "deb", "rpm"]),
+ &[("os", 1.1, 0.), ("os::unix-apis", 1.4, 0.1), ("os::macos-apis", 0.2, 0.), ("os::windows-apis", 0.1, 0.)]),
+ (Cond::Any(&["glib", "gobject", "gdk"]), &[("os", 1.1, 0.), ("os::unix-apis", 1.4, 0.1)]),
+ (Cond::Any(&["fedora", "centos", "redhat", "debian"]),
+ &[("os::unix-apis", 1.3, 0.1), ("os::macos-apis", 0.1, 0.), ("os::windows-apis", 0.1, 0.)]),
+ (Cond::All(&["linux", "kernel"]), &[("os::unix-apis", 1.3, 0.2), ("multimedia::encoding", 0.8, 0.)]),
+ (Cond::All(&["api", "kernel"]), &[("os::unix-apis", 1.1, 0.), ("os", 1.1, 0.)]),
+ (Cond::Any(&["dylib"]), &[("os", 1.1, 0.), ("os::windows-apis", 0.6, 0.)]),
+ (Cond::Any(&["so"]), &[("os", 1.1, 0.), ("os::windows-apis", 0.6, 0.), ("os::macos-apis", 0.6, 0.)]),
+ (Cond::Any(&["dll"]), &[("os", 1.1, 0.), ("os::unix-apis", 0.6, 0.), ("os::macos-apis", 0.6, 0.)]),
+ (Cond::Any(&["redox", "rtos", "embedded"]), &[("os", 1.2, 0.1), ("gui", 0.8, 0.), ("os::macos-apis", 0., 0.), ("os::windows-apis", 0., 0.)]),
+ (Cond::Any(&["rtos", "embedded", "microkernel"]), &[("embedded", 1.3, 0.1), ("science::math", 0.7, 0.)]),
+ (Cond::All(&["operating", "system"]), &[("os", 1.2, 0.2)]),
+ (Cond::Any(&["signal"]),
+ &[("os::unix-apis", 1.2, 0.), ("date-and-time", 0.4, 0.), ("memory-management", 0.8, 0.), ("games", 0.6, 0.),
+ ("gui", 0.9, 0.), ("game-engines", 0.8, 0.), ("multimedia::images", 0.5, 0.),
+ ("command-line-utilities", 0.7, 0.), ("development-tools", 0.8, 0.), ("science::math", 0.7, 0.)]),
+ (Cond::Any(&["autotools", "ld_preload", "libnotify", "syslog", "systemd", "seccomp", "kill"]),
+ &[("os::unix-apis", 1.2, 0.05), ("date-and-time", 0.1, 0.), ("memory-management", 0.6, 0.), ("games", 0.2, 0.), ("multimedia::audio", 0.5, 0.),
+ ("gui", 0.9, 0.), ("game-engines", 0.6, 0.), ("multimedia::images", 0.2, 0.),
+ ("command-line-utilities", 0.8, 0.), ("science::math", 0.6, 0.)]),
+ (Cond::Any(&["epoll", "affinity", "sigint", "syscall", "ioctl", "unix-socket", "unix-sockets"]),
+ &[("os::unix-apis", 1.3, 0.1), ("date-and-time", 0.1, 0.), ("memory-management", 0.6, 0.), ("games", 0.2, 0.), ("multimedia::audio", 0.5, 0.),
+ ("gui", 0.8, 0.), ("game-engines", 0.6, 0.), ("multimedia::images", 0.2, 0.),
+ ("command-line-utilities", 0.6, 0.), ("development-tools", 0.9, 0.), ("science::math", 0.6, 0.)]),
+ (Cond::Any(&["arch-linux", "unix", "archlinux", "docker", "pacman", "systemd", "posix", "x11", "epoll"]),
+ &[("os::unix-apis", 1.2, 0.2), ("no-std", 0.5, 0.), ("multimedia::audio", 0.8, 0.), ("os::windows-apis", 0.7, 0.), ("cryptography", 0.8, 0.), ("cryptography::cryptocurrencies", 0.6, 0.)]),
+ (Cond::Any(&["docker", "kubernetes", "k8s", "devops"]),
+ &[("development-tools", 1.2, 0.1), ("web-programming", 1.1, 0.02), ("os::macos-apis", 0.9, 0.), ("config", 0.9, 0.), ("os::windows-apis", 0.1, 0.), ("command-line-utilities", 1.1, 0.02)]),
+ (Cond::Any(&["ios"]), &[("development-tools::profiling", 0.8, 0.), ("os::windows-apis", 0.1, 0.), ("development-tools::cargo-plugins", 0.8, 0.)]),
+ (Cond::Any(&["android"]), &[("os::macos-apis", 0.5, 0.), ("os::windows-apis", 0.7, 0.), ("os::unix-apis", 0.9, 0.), ("development-tools::profiling", 0.9, 0.)]),
+ (Cond::Any(&["cross-platform", "portable"]), &[("os::macos-apis", 0.25, 0.), ("os::windows-apis", 0.25, 0.), ("os::unix-apis", 0.25, 0.)]),
+ (Cond::All(&["cross", "platform"]), &[("os::macos-apis", 0.25, 0.), ("os::windows-apis", 0.25, 0.), ("os::unix-apis", 0.25, 0.)]),
+ (Cond::All(&["freebsd", "windows"]), &[("os::macos-apis", 0.6, 0.), ("os::windows-apis", 0.8, 0.), ("os::unix-apis", 0.8, 0.)]),
+ (Cond::All(&["linux", "windows"]), &[("os::macos-apis", 0.5, 0.), ("os::windows-apis", 0.8, 0.), ("os::unix-apis", 0.8, 0.)]),
+ (Cond::All(&["macos", "windows"]), &[("os::macos-apis", 0.8, 0.), ("os::windows-apis", 0.5, 0.), ("os::unix-apis", 0.5, 0.)]),
+
+ (Cond::NotAny(&["has:is_sys", "ffi", "sys", "bindings", "c", "libc", "libffi", "cstr", "python", "ruby", "lua", "erlang", "unsafe"]),
+ &[("development-tools::ffi", 0.7, 0.)]),
+ (Cond::Any(&["ffi"]), &[("development-tools::ffi", 1.2, 0.), ("games", 0.1, 0.), ("filesystem", 0.9, 0.)]),
+ (Cond::Any(&["sys"]), &[("development-tools::ffi", 0.9, 0.), ("games", 0.4, 0.), ("asynchronous", 0.9, 0.), ("rendering::engine", 0.8, 0.), ("rendering", 0.8, 0.), ("multimedia", 0.9, 0.)]),
+ (Cond::Any(&["has:is_sys"]), &[("development-tools::ffi", 0.1, 0.), ("no-std", 0.7, 0.), ("data-structures", 0.9,